blob: c010f4c6bfa260c998e51fec50c081d719da3ba6 [file] [log] [blame]
#include "common.h"
#define LINE_LEN 79
#define STATUS_LEN 22
#define PROGBAR_MAX (LINE_LEN - STATUS_LEN - 1)
static char status_msg[128];
static int progbar_scale = 0;
static int progbar_len = 0;
static int progbar_pos = -1;
int quietmode = 0;
int errorlog = 0;
static png_uint_32 counter;
static png_uint_32 maxcount;
static int barlen;
#define isoption(p) (IsOptChar((p)[0]) && (p)[1]!='\0')
static void print_status(void)
{
fprintf(stderr, "\r%-*.*s ", STATUS_LEN, STATUS_LEN, status_msg);
fflush(stderr);
progbar_pos = 0;
}
static void put_dots(int dotchar, int num)
{
int i;
if (num > PROGBAR_MAX) num = PROGBAR_MAX;
if (progbar_pos == -1) print_status();
for (i = progbar_pos; i < num; i++)
fputc(dotchar, stderr);
if (progbar_pos < num) {
progbar_pos = num;
fflush(stderr);
}
}
static void print_scale(void)
{
if (progbar_pos != 0) print_status();
put_dots('.', progbar_len);
print_status();
progbar_scale = 1;
}
static void init_progress_bar(int max)
{
if (quietmode) return;
progbar_len = max;
print_scale();
}
static void update_progress_bar(int num)
{
if (quietmode) return;
if (!progbar_scale) print_scale();
put_dots('o', num);
}
static void clear_line(void)
{
if (quietmode) return;
fprintf(stderr, "\r%*c\r", LINE_LEN, ' ');
progbar_scale = 0;
progbar_pos = -1;
}
void xxprintf(const char *fmt, ...)
{
va_list ap;
FILE *f;
va_start(ap, fmt);
clear_line();
vfprintf(stderr, fmt, ap);
fflush(stderr);
if (errorlog && (f = fopen(errlogfile, "a")) != NULL) {
vfprintf(f, fmt, ap);
fclose(f);
}
va_end(ap);
}
void set_status(const char *fmt, ...)
{
va_list ap;
if (quietmode) return;
va_start(ap, fmt);
vsprintf(status_msg, fmt, ap);
va_end(ap);
print_status();
}
void feed_line(void)
{
if (quietmode) return;
fputc('\n', stderr);
fflush(stderr);
progbar_scale = 0;
progbar_pos = -1;
}
static png_uint_32 maxcount_adam7(png_uint_32 width, png_uint_32 height)
{
png_uint_32 c = 0;
if ( 1 ) c += ((height - 0 + 7) / 8) * 1;
if (width > 4) c += ((height - 0 + 7) / 8) * 1;
if ( 1 ) c += ((height - 4 + 7) / 8) * 2;
if (width > 2) c += ((height - 0 + 3) / 4) * 2;
if ( 1 ) c += ((height - 2 + 3) / 4) * 4;
if (width > 1) c += ((height - 0 + 1) / 2) * 4;
if ( 1 ) c += ((height - 1 + 1) / 2) * 8;
return c;
}
void init_progress_meter(png_structp png_ptr, png_uint_32 width,
png_uint_32 height)
{
enum { W = 1024, H = 768 };
if (png_set_interlace_handling(png_ptr) == 7) {
maxcount = maxcount_adam7(width, height);
} else {
maxcount = height;
}
if (height > ((png_uint_32)W * H) / width) {
barlen = PROGBAR_MAX;
} else {
barlen = (PROGBAR_MAX * width * height + (W * H - 1)) / (W * H);
}
counter = 0;
init_progress_bar(barlen);
}
void row_callback(png_structp png_ptr, png_uint_32 row, int pass)
{
if (row == 0) pass--;
counter += (1 << (pass >> 1)); /* step[pass]; */
update_progress_bar(barlen * counter / maxcount);
}
FILE *binary_stdio(int fd)
{
FILE *fp;
if (fd != 0 && fd != 1)
return NULL;
printf("---------binary_stdio----else ------\n");
fp = (fd == 0) ? stdin : stdout;
return fp;
}
char *suffix(const char *path)
{
char c, *p, *q, *r;
for (r = q = p = basname(path); (c = *p) != '\0'; p++)
if (c == '.') q = p;
if (q == r) q = p; /* dotfile with no suffix */
return q;
}
char *basname(const char *path)
{
const char *p, *q;
for (p = path_skiproot(path);
*(q = path_nextslash(p)) != '\0'; p = q + 1) ;
return (char *)p;
}
char *addslash(char *path)
{
char *p, *q;
for (p = path_skiproot(path);
*(q = path_nextslash(p)) != '\0'; p = q + 1) ;
if (q != p) {
*q++ = PATHDELIM;
*q = '\0';
}
return path;
}
char *path_skiproot(const char *path)
{
if (IsPathDelim(path[0])) path++;
return (char *)path;
}
char *path_nextslash(const char *path)
{
char c;
for (; (c = *path) != '\0'; path++) {
if (IsDBCSLead((unsigned char)c)) {
if (*(++path) == '\0') break;
continue;
}
if (IsPathDelim(c)) break;
}
return (char *)path;
}
char *delslash(char *path)
{
char *p, *q, *s;
for (p = s = path_skiproot(path);
*(q = path_nextslash(p)) != '\0'; p = q + 1) ;
if (q == s) {
*q++ = '.';
*q = '\0';
} else if (q == p) {
*--q = '\0';
}
return path;
}
void png_my_error(png_structp png_ptr, png_const_charp message)
{
xxprintf("ERROR(libpng): %s - %s\n", message,
(char *)png_get_error_ptr(png_ptr));
longjmp(png_jmpbuf(png_ptr), 1);
}
void png_my_warning(png_structp png_ptr, png_const_charp message)
{
xxprintf("WARNING(libpng): %s - %s\n", message,
(char *)png_get_error_ptr(png_ptr));
}
BOOL imgbuf_alloc(IMAGE *img)
{
BYTE *bp, **rp;
LONG n;
if (img->palnum > 0) {
img->palette = malloc((size_t)img->palnum * sizeof(PALETTE));
if (img->palette == NULL) { imgbuf_init(img); return FALSE; }
} else {
img->palette = NULL;
}
img->rowbytes = ((DWORD)img->width * img->pixdepth + 31) / 32 * 4;
img->imgbytes = img->rowbytes * img->height;
img->rowptr = malloc((size_t)img->height * sizeof(BYTE *));
img->bmpbits = malloc((size_t)img->imgbytes);
if (img->rowptr == NULL || img->bmpbits == NULL) {
imgbuf_free(img); imgbuf_init(img); return FALSE;
}
n = img->height;
rp = img->rowptr;
bp = img->bmpbits;
if (img->topdown) {
while (--n >= 0) {
*(rp++) = bp;
bp += img->rowbytes;
}
} else { /* bottom-up */
bp += img->imgbytes;
while (--n >= 0) {
((DWORD *)bp)[-1] = 0;
bp -= img->rowbytes;
*(rp++) = bp;
}
}
return TRUE;
}
void imgbuf_free(IMAGE *img)
{
free(img->palette);
free(img->rowptr);
free(img->bmpbits);
}
void imgbuf_init(IMAGE *img)
{
img->palette = NULL;
img->rowptr = NULL;
img->bmpbits = NULL;
}
int parsearg(int *opt, char **arg, int argc, char **argv, char *aopts)
{
static int agi = 1;
static char *agp = NULL;
char *p;
int c, i;
if (agp != NULL && *agp == '\0') {
agp = NULL;
agi++;
}
if (agi >= argc)
return 0;
if (p = argv[agi], agp == NULL && !isoption(p)) {
c = 0;
agi++;
} else {
if (agp == NULL) agp = p + 1;
if (c = (*agp & 0xFF), strchr(aopts, c) != NULL) {
if (p = agp + 1, *p != '\0') {
/*NULL*/;
} else if (i = agi + 1, p = argv[i], i < argc && !isoption(p)) {
agi = i;
} else {
p = NULL;
}
agp = NULL;
agi++;
} else {
p = NULL;
agp++;
}
}
*opt = c;
*arg = p;
return 1;
}
char **envargv(int *argcp, char ***argvp, const char *envn)
{
int argc, nagc, envc, i;
char **argv, **nagv, *envs, *ep;
ep = getenv(envn);
if (ep == NULL || ep[0] == '\0') return NULL;
envs = malloc(strlen(ep) + 1);
if (envs == NULL) return NULL;
strcpy(envs, ep);
envc = tokenize(envs, envs);
if (envc == 0) { free(envs); return NULL; }
argc = *argcp;
argv = *argvp;
nagv = malloc((argc + envc + 1) * sizeof(char *));
if (nagv == NULL) { free(envs); return NULL; }
nagc = 1;
nagv[0] = argv[0];
for (i = 0; i < envc; i++) {
nagv[nagc++] = envs;
while (*(envs++) != '\0') ;
}
for (i = 1; i < argc; i++) {
nagv[nagc++] = argv[i];
}
nagv[nagc] = NULL;
*argcp = nagc;
*argvp = nagv;
return argv;
}
int tokenize(char *buf, const char *str)
{
enum { STR = 0x01, QUOTE = 0x02 };
int flag = 0;
int num = 0;
char c;
int i;
while ((c = *str++) != '\0') {
if (!(flag & QUOTE) &&
(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {
if (flag & STR) {
flag &= ~STR;
*buf++ = '\0';
}
} else {
if (!(flag & STR)) {
flag |= STR;
num++;
}
switch (c) {
case '\\':
for (i = 1; (c = *str) == '\\'; str++, i++) ;
if (c == '"') {
while ((i -= 2) >= 0)
*buf++ = '\\';
if (i == -1) {
*buf++ = '"';
str++;
}
} else {
while ((--i) >= 0)
*buf++ = '\\';
}
break;
case '"':
flag ^= QUOTE;
break;
default:
*buf++ = c;
}
}
}
if (flag & STR) *buf = '\0';
return num;
}
int makedir(const char *path)
{
char dir[FILENAME_MAX];
struct stat sbuf;
char *p, c;
int r;
delslash(strcpy(dir, path));
if (stat(dir, &sbuf) == 0) {
if ((sbuf.st_mode & S_IFMT) == S_IFDIR) return 0;
return -1;
}
p = path_skiproot(dir);
do {
p = path_nextslash(p);
c = *p; *p = '\0';
r = MKDIR(dir, 0777);
*p++ = c;
} while (c != '\0');
return r;
}
int renbak(const char *path)
{
char bak[FILENAME_MAX];
struct stat sbuf;
char *sfx;
int i;
strcpy(bak, path);
if (stat(bak, &sbuf) != 0) return 0;
sfx = bak + strlen(bak);
strcpy(sfx, ".bak");
i = 0;
while (1) {
if (stat(bak, &sbuf) != 0 && rename(path, bak) == 0) return 0;
if (i >= 1000) break;
sprintf(sfx, ".%03d", i++);
}
return -1;
}
int cpyftime(const char *srcf, const char *dstf)
{
struct stat sbuf;
struct utimbuf ubuf;
if (stat(srcf, &sbuf) != 0) return -1;
ubuf.actime = sbuf.st_atime;
ubuf.modtime = sbuf.st_mtime;
return utime(dstf, &ubuf);
}