static gbm_boolean show(const char *fn, const char *opt) { gbm_boolean ret = GBM_TRUE; int fd; struct stat buf; if ( stat(fn, &buf) != -1 && (buf.st_mode & S_IFDIR) == S_IFDIR ) /* Is a directory */ { show_error(fn, "is a directory"); return GBM_FALSE; } if ( (fd = gbm_io_open(fn, GBM_O_RDONLY)) == -1 ) { show_error(fn, "can't open"); return GBM_FALSE; } if ( guess ) { ret = show_guess(fn, opt, fd); } else { show_noguess(fn, opt, fd); } gbm_io_close(fd); return ret; }
int main(int argc, char *argv[]) { GBMTOOL_FILEARG gbmfilearg; char fn_src[GBMTOOL_FILENAME_MAX+1], fn_dst[GBMTOOL_FILENAME_MAX+1], opt_src[GBMTOOL_OPTIONS_MAX+1], opt_dst[GBMTOOL_OPTIONS_MAX+1]; int w = -1, h = -1, filterIndex = FILTER_INDEX_SIMPLE; int fd, ft_src, ft_dst, i, flag; size_t stride, stride2; GBM_ERR rc; GBMFT gbmft; GBM gbm, gbm2; GBMRGB gbmrgb[0x100]; gbm_boolean aspect = GBM_FALSE; gbm_boolean qualityScalingEnabled = GBM_FALSE; gbm_boolean isGrayscale = GBM_FALSE; gbm_u8 *data, *data2; #ifdef MEASURE_TIME #if defined(__OS2__) DATETIME start_time, end_time; double time_s; #elif defined(WIN32) SYSTEMTIME start_time, end_time; double time_s; #elif defined(LINUX) struct timeval start_time, end_time; double time_s; #endif #endif for ( i = 1; i < argc; i++ ) { if ( argv[i][0] != '-' ) break; else if ( argv[i][1] == '-' ) { ++i; break; } switch ( argv[i][1] ) { case 'w': if ( ++i == argc ) usage(); w = get_opt_value_pos(argv[i], "w"); break; case 'h': if ( ++i == argc ) usage(); h = get_opt_value_pos(argv[i], "h"); break; case 'a': aspect = GBM_TRUE; break; case 'f': if ( ++i == argc ) usage(); filterIndex = get_opt_value_filterIndex(argv[i], FILTER_NAME_TABLE, FILTER_NAME_TABLE_LENGTH); break; default: usage(); break; } } if ( aspect && w == -1 && h == -1 ) { fatal("-a can't be used if neither -w or -h is given"); } if (filterIndex == -1) { fatal("wrong filter type"); } else if (filterIndex != FILTER_INDEX_SIMPLE) { qualityScalingEnabled = GBM_TRUE; } if ( i == argc ) usage(); /* Split filename and file options. */ gbmfilearg.argin = argv[i++]; if (strcmp(gbmfilearg.argin, "\"\"") == 0) { usage(); } if (gbmtool_parse_argument(&gbmfilearg, GBM_FALSE) != GBM_ERR_OK) { fatal("can't parse source filename %s", gbmfilearg.argin); } strcpy(fn_src , gbmfilearg.files->filename); strcpy(opt_src, gbmfilearg.options); gbmtool_free_argument(&gbmfilearg); gbmfilearg.argin = (i == argc) ? argv[i-1] : argv[i++]; if (strcmp(gbmfilearg.argin, "\"\"") == 0) { usage(); } if (gbmtool_parse_argument(&gbmfilearg, GBM_FALSE) != GBM_ERR_OK) { fatal("can't parse destination filename %s", gbmfilearg.argin); } strcpy(fn_dst , gbmfilearg.files->filename); strcpy(opt_dst, gbmfilearg.options); gbmtool_free_argument(&gbmfilearg); if (i < argc) usage(); #ifdef MEASURE_TIME #if defined(__OS2__) DosGetDateTime(&start_time); #elif defined(WIN32) GetSystemTime(&start_time); #elif defined(LINUX) gettimeofday(&start_time, NULL); #endif #endif /* processing */ gbm_init(); if ( gbm_guess_filetype(fn_src, &ft_src) != GBM_ERR_OK ) fatal("can't guess bitmap file format for %s", fn_src); if ( gbm_guess_filetype(fn_dst, &ft_dst) != GBM_ERR_OK ) fatal("can't guess bitmap file format for %s", fn_dst); if ( (fd = gbm_io_open(fn_src, GBM_O_RDONLY)) == -1 ) fatal("can't open %s", fn_src); if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK ) { gbm_io_close(fd); fatal("can't read header of %s: %s", fn_src, gbm_err(rc)); } /* check for color depth supported by algorithms */ switch ( gbm.bpp ) { case 64: case 48: case 32: case 24: case 8: case 4: case 1: break; default: { gbm_io_close(fd); fatal("%d bpp file is not supported", gbm.bpp); } } if ( aspect && (w != -1) && (h != -1)) { if (((float)w/gbm.w) <= ((float)h/gbm.h)) { h = ( gbm.h * w ) / gbm.w; } else { w = ( gbm.w * h ) / gbm.h; } } else { if ( w == -1 ) { if ( aspect ) w = ( gbm.w * h ) / gbm.h; else w = gbm.w; } if ( h == -1 ) { if ( aspect ) h = ( gbm.h * w ) / gbm.w; else h = gbm.h; } } if (w == 0 || h == 0) { gbm_io_close(fd); fatal("desired bitmap size of %dx%d, is silly", w, h); } if ( (rc = gbm_read_palette(fd, ft_src, &gbm, gbmrgb)) != GBM_ERR_OK ) { gbm_io_close(fd); fatal("can't read palette of %s: %s", fn_src, gbm_err(rc)); } gbm2 = gbm; gbm2.w = w; gbm2.h = h; if (qualityScalingEnabled) { if (gbm.bpp <= 8) { isGrayscale = isGrayscalePalette(gbmrgb, 1 << gbm.bpp); } if ((gbm.bpp <= 8) && (! isGrayscale)) { gbm_io_close(fd); fatal("can't use filter '%s' for colour palette images", FILTER_NAME_TABLE[filterIndex].name); } if (isGrayscale) { gbm2.bpp = 8; } } stride = ( ((gbm.w * gbm.bpp + 31)/32) * 4 ); if ( (data = gbmmem_malloc(stride * gbm.h)) == NULL ) { gbm_io_close(fd); #if (ULONG_MAX > UINT_MAX) fatal("out of memory allocating %zu bytes for input bitmap", stride * gbm.h); #else fatal("out of memory allocating %u bytes for input bitmap", stride * gbm.h); #endif } stride2 = ( ((gbm2.w * gbm2.bpp + 31)/32) * 4 ); if ( (data2 = gbmmem_malloc(stride2 * gbm2.h)) == NULL ) { gbmmem_free(data); gbm_io_close(fd); #if (ULONG_MAX > UINT_MAX) fatal("out of memory allocating %zu bytes for output bitmap", stride2 * gbm2.h); #else fatal("out of memory allocating %u bytes for output bitmap", stride2 * gbm2.h); #endif } if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK ) { gbmmem_free(data2); gbmmem_free(data); gbm_io_close(fd); fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc)); } gbm_io_close(fd); #ifdef MEASURE_TIME #if defined(__OS2__) DosGetDateTime(&end_time); time_s = ((double) (end_time .minutes * 60) + end_time .seconds + (end_time .hundredths/100.0)) - ((double) (start_time.minutes * 60) + start_time.seconds + (start_time.hundredths/100.0)); printf("Elapsed time LOAD : %lf\n", time_s); #elif defined(WIN32) GetSystemTime(&end_time); time_s = ((double) (end_time .wMinute * 60) + end_time .wSecond + (end_time .wMilliseconds/1000.0)) - ((double) (start_time.wMinute * 60) + start_time.wSecond + (start_time.wMilliseconds/1000.0)); printf("Elapsed time LOAD : %lf\n", time_s); #elif defined(LINUX) gettimeofday(&end_time, NULL); time_s = ((double) (end_time .tv_sec) + (end_time .tv_usec/1000000.0)) - ((double) (start_time.tv_sec) + (start_time.tv_usec/1000000.0)); printf("Elapsed time LOAD : %lf\n", time_s); #endif #endif #ifdef MEASURE_TIME #if defined(__OS2__) DosGetDateTime(&start_time); #elif defined(WIN32) GetSystemTime(&start_time); #elif defined(LINUX) gettimeofday(&start_time, NULL); #endif #endif if (qualityScalingEnabled) { if (isGrayscale) { rc = gbm_quality_scale_gray(data , gbm.w , gbm.h , gbm.bpp, gbmrgb, data2, gbm2.w, gbm2.h, gbmrgb, FILTER_NAME_TABLE[filterIndex].filter); } else { rc = gbm_quality_scale_bgra(data , gbm.w , gbm.h, data2, gbm2.w, gbm2.h, gbm.bpp, FILTER_NAME_TABLE[filterIndex].filter); } } else { rc = gbm_simple_scale(data, gbm.w, gbm.h, data2, gbm2.w, gbm2.h, gbm.bpp); } #ifdef MEASURE_TIME #if defined(__OS2__) DosGetDateTime(&end_time); time_s = ((double) (end_time .minutes * 60) + end_time .seconds + (end_time .hundredths/100.0)) - ((double) (start_time.minutes * 60) + start_time.seconds + (start_time.hundredths/100.0)); printf("Elapsed time SCALE: %lf\n", time_s); #elif defined(WIN32) GetSystemTime(&end_time); time_s = ((double) (end_time .wMinute * 60) + end_time .wSecond + (end_time .wMilliseconds/1000.0)) - ((double) (start_time.wMinute * 60) + start_time.wSecond + (start_time.wMilliseconds/1000.0)); printf("Elapsed time SCALE: %lf\n", time_s); #elif defined(LINUX) gettimeofday(&end_time, NULL); time_s = ((double) (end_time .tv_sec) + (end_time .tv_usec/1000000.0)) - ((double) (start_time.tv_sec) + (start_time.tv_usec/1000000.0)); printf("Elapsed time SCALE: %lf\n", time_s); #endif #endif gbmmem_free(data); if (rc != GBM_ERR_OK) { gbmmem_free(data2); fatal("can't scale: %s", gbm_err(rc)); } #ifdef MEASURE_TIME #if defined(__OS2__) DosGetDateTime(&start_time); #elif defined(WIN32) GetSystemTime(&start_time); #elif defined(LINUX) gettimeofday(&start_time, NULL); #endif #endif if ( (fd = gbm_io_create(fn_dst, GBM_O_WRONLY)) == -1 ) { gbmmem_free(data2); fatal("can't create %s", fn_dst); } gbm_query_filetype(ft_dst, &gbmft); switch ( gbm2.bpp ) { case 64: flag = GBM_FT_W64; break; case 48: flag = GBM_FT_W48; break; case 32: flag = GBM_FT_W32; break; case 24: flag = GBM_FT_W24; break; case 8: flag = GBM_FT_W8; break; case 4: flag = GBM_FT_W4; break; case 1: flag = GBM_FT_W1; break; default: flag = 0; break; } if ( (gbmft.flags & flag) == 0 ) { gbm_io_close(fd); fatal("output bitmap format %s does not support writing %d bpp data", gbmft.short_name, gbm2.bpp); } if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm2, gbmrgb, data2, opt_dst)) != GBM_ERR_OK ) { gbm_io_close(fd); remove(fn_dst); gbmmem_free(data2); fatal("can't write %s: %s", fn_dst, gbm_err(rc)); } gbm_io_close(fd); gbmmem_free(data2); gbm_deinit(); #ifdef MEASURE_TIME #if defined(__OS2__) DosGetDateTime(&end_time); time_s = ((double) (end_time .minutes * 60) + end_time .seconds + (end_time .hundredths/100.0)) - ((double) (start_time.minutes * 60) + start_time.seconds + (start_time.hundredths/100.0)); printf("Elapsed time WRITE: %lf\n", time_s); #elif defined(WIN32) GetSystemTime(&end_time); time_s = ((double) (end_time .wMinute * 60) + end_time .wSecond + (end_time .wMilliseconds/1000.0)) - ((double) (start_time.wMinute * 60) + start_time.wSecond + (start_time.wMilliseconds/1000.0)); printf("Elapsed time WRITE: %lf\n", time_s); #elif defined(LINUX) gettimeofday(&end_time, NULL); time_s = ((double) (end_time .tv_sec) + (end_time .tv_usec/1000000.0)) - ((double) (start_time.tv_sec) + (start_time.tv_usec/1000000.0)); printf("Elapsed time WRITE: %lf\n", time_s); #endif #endif return 0; }
// use GBM library to read image file params: int TestGBMfile( const char *fn, int *w, int *h, int *bpp, int *n ) { // set w=width, h=height, bpp=bits per pixel, n = images in stack int fd, ft, num; // return 0 if format not recognized; filetype > 0 otherwise GBM gbm; GBMRGB *gbmrgb; GBM_ERR rc; char opt[64], buf[32], errmsg[80]; HANDLE file; DWORD numbytesread; // first see what GBM makes of the filename if ( gbm_guess_filetype(fn, &ft) != GBM_ERR_OK ) { // need to check header, so open the file... file = CreateFile( fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); ft = -1; if ( file ) { // if successful, read first characters strcpy(buf,"000000000000000000000"); // clear buffer ReadFile( file, buf, 20, &numbytesread, NULL ); // read from file CloseHandle( file ); if ( !(strncmp(buf, "\x42\x4D", 2)) ) ft = 0; // Windows Bitmap else if ( !(strncmp(buf, "\x47\x49\x46", 3)) ) ft = 1; // GIF else if ( !(strncmp(buf, "\x49\x49\x2A\x00", 4)) ) ft = 3; // TIFF else if ( !(strncmp(buf, "\x4D\x4D\x00\x2A", 4)) ) ft = 3; // TIFF else if ( !(strncmp(buf, "\xff\xd8\xff", 3)) ) ft = 16; // JPEG } } if ( ft >= 0 ) // if found a valid filetype { if ( (fd = gbm_io_open(fn, O_RDONLY|O_BINARY)) == -1 ) // open file { sprintf(errmsg,"Can't open %s", fn); ErrMsgOK( ERRMSG_READ_FAILED, errmsg ); return 0; } opt[0] = '\0'; // no option string used if ( (rc = gbm_read_header(fn, fd, ft, &gbm, opt)) != GBM_ERR_OK ) // read header { sprintf(errmsg,"Can't read header of %s.\nError is %d.", fn, rc); ErrMsgOK( ERRMSG_READ_FAILED, errmsg ); gbm_io_close(fd); return 0; } *w = gbm.w; // width in pixels *h = gbm.h; // height in pixels *bpp = gbm.bpp; // bits per pixel num = 1; // there's always at least one image sprintf(opt,"index=%d",num); // if GIF or TIFF there could be more images if ( (ft==1) || (ft==3) ) while ( gbm_read_header(fn, fd, ft, &gbm, opt) == GBM_ERR_OK ) { num++; // count through rest of images in file sprintf(opt,"index=%d",num); // final n is number of images in stack } *n = num; // update passed variable (1 more than index of last image) gbm_io_close(fd); } return ft+1; // offset GBM types by one so zero is "file not recognized" }
int gbmBmpToGif(char *fn_src, char *fn_dst) { int w = -1, h = -1; char opt_src[] = ""; char opt_dst[] = ""; int fd, ft_src, ft_dst, stride, flag; GBM_ERR rc; GBMFT gbmft; GBM gbm; GBMRGB gbmrgb[0x100]; byte *data; gbm_init(); ft_src = 0; ft_dst = 1; if ( (fd = gbm_io_open(fn_src, O_RDONLY|O_BINARY)) == -1 ) { // fatal("can't open %s", fn_src); return 1; } if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK ) { gbm_io_close(fd); // fatal("can't read header of %s: %s", fn_src, gbm_err(rc)); return 2; } w = gbm.w; h = gbm.h; gbm_query_filetype(ft_dst, &gbmft); switch ( gbm.bpp ) { case 24: flag = GBM_FT_W24;break; case 8: flag = GBM_FT_W8; break; case 4: flag = GBM_FT_W4; break; case 1: flag = GBM_FT_W1; break; } if ( (gbmft.flags & flag) == 0 ) { gbm_io_close(fd); // fatal("output bitmap format %s does not support writing %d bpp data", gbmft.short_name, gbm.bpp); return 3; } if ( (rc = gbm_read_palette(fd, ft_src, &gbm, gbmrgb)) != GBM_ERR_OK ) { gbm_io_close(fd); // fatal("can't read palette of %s: %s", fn_src, gbm_err(rc)); return 4; } stride = ( ((gbm.w * gbm.bpp + 31)/32) * 4 ); if ( (data = (byte *)malloc((size_t) (stride * gbm.h))) == NULL ) { gbm_io_close(fd); // fatal("out of memory allocating %d bytes for input bitmap", stride * gbm.h); return 5; } if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK ) { free(data); gbm_io_close(fd); // fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc)); return 6; } gbm_io_close(fd); extern int bAppendMode; if (bAppendMode) { if ( (fd = gbm_io_open(fn_dst, O_RDWR|O_BINARY)) == -1 ) { free(data); // fatal("can't create %s", fn_dst); return 7; } gbm_io_lseek(fd, -1, SEEK_END); } else { if ( (fd = gbm_io_create(fn_dst, O_WRONLY|O_BINARY)) == -1 ) { free(data); // fatal("can't create %s", fn_dst); return 7; } } gbm.w = w; gbm.h = h; if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm, gbmrgb, data, opt_dst)) != GBM_ERR_OK ) { gbm_io_close(fd); remove(fn_dst); free(data); // fatal("can't write %s: %s", fn_dst, gbm_err(rc)); return 8; } gbm_io_close(fd); free(data); gbm_deinit(); return 0; }
/*...smain:0:*/ int main(int argc, char *argv[]) { GBMTOOL_FILEARG gbmfilearg; char fn_src[GBMTOOL_FILENAME_MAX+1], fn_dst[GBMTOOL_FILENAME_MAX+1], opt_src[GBMTOOL_OPTIONS_MAX+1], opt_dst[GBMTOOL_OPTIONS_MAX+1]; int x = 0, y = 0, w = -1, h = -1; int fd, ft_src, ft_dst, i, flag; size_t stride_src, bytes; GBM_ERR rc; GBMFT gbmft; GBM gbm; GBMRGB gbmrgb[0x100]; gbm_u8 *data; for ( i = 1; i < argc; i++ ) { if ( argv[i][0] != '-' ) break; else if ( argv[i][1] == '-' ) { ++i; break; } switch ( argv[i][1] ) { case 'x': if ( ++i == argc ) usage(); x = get_opt_value_pos(argv[i], "x"); break; case 'y': if ( ++i == argc ) usage(); y = get_opt_value_pos(argv[i], "y"); break; case 'w': if ( ++i == argc ) usage(); w = get_opt_value_pos(argv[i], "w"); break; case 'h': if ( ++i == argc ) usage(); h = get_opt_value_pos(argv[i], "h"); break; default: usage(); break; } } if ( i == argc ) usage(); /* Split filename and file options. */ gbmfilearg.argin = argv[i++]; if (strcmp(gbmfilearg.argin, "\"\"") == 0) { usage(); } if (gbmtool_parse_argument(&gbmfilearg, GBM_FALSE) != GBM_ERR_OK) { fatal("can't parse source filename %s", gbmfilearg.argin); } strcpy(fn_src , gbmfilearg.files->filename); strcpy(opt_src, gbmfilearg.options); gbmtool_free_argument(&gbmfilearg); gbmfilearg.argin = (i == argc) ? argv[i-1] : argv[i++]; if (strcmp(gbmfilearg.argin, "\"\"") == 0) { usage(); } if (gbmtool_parse_argument(&gbmfilearg, GBM_FALSE) != GBM_ERR_OK) { fatal("can't parse destination filename %s", gbmfilearg.argin); } strcpy(fn_dst , gbmfilearg.files->filename); strcpy(opt_dst, gbmfilearg.options); gbmtool_free_argument(&gbmfilearg); if (i < argc) usage(); /* processing */ gbm_init(); if ( gbm_guess_filetype(fn_src, &ft_src) != GBM_ERR_OK ) fatal("can't guess bitmap file format for %s", fn_src); if ( gbm_guess_filetype(fn_dst, &ft_dst) != GBM_ERR_OK ) fatal("can't guess bitmap file format for %s", fn_dst); if ( (fd = gbm_io_open(fn_src, GBM_O_RDONLY)) == -1 ) fatal("can't open %s", fn_src); if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK ) { gbm_io_close(fd); fatal("can't read header of %s: %s", fn_src, gbm_err(rc)); } /* check for color depth supported by algorithms */ switch ( gbm.bpp ) { case 64: case 48: case 32: case 24: case 8: case 4: case 1: break; default: { gbm_io_close(fd); fatal("%d bpp file is not supported", gbm.bpp); } } if ( w == -1 ) w = gbm.w - x; if ( h == -1 ) h = gbm.h - y; if ( w == 0 ) { gbm_io_close(fd); fatal("w = 0"); } if ( h == 0 ) { gbm_io_close(fd); fatal("h = 0"); } if ( x >= gbm.w ) { gbm_io_close(fd); fatal("x >= bitmap width"); } if ( y >= gbm.h ) { gbm_io_close(fd); fatal("y >= bitmap height"); } if ( x + w > gbm.w ) { gbm_io_close(fd); fatal("x+w > bitmap width"); } if ( y + h > gbm.h ) { gbm_io_close(fd); fatal("y+h > bitmap height"); } gbm_query_filetype(ft_dst, &gbmft); switch ( gbm.bpp ) { case 64: flag = GBM_FT_W64; break; case 48: flag = GBM_FT_W48; break; case 32: flag = GBM_FT_W32; break; case 24: flag = GBM_FT_W24; break; case 8: flag = GBM_FT_W8; break; case 4: flag = GBM_FT_W4; break; case 1: flag = GBM_FT_W1; break; default: flag = 0; break; } if ( (gbmft.flags & flag) == 0 ) { gbm_io_close(fd); fatal("output bitmap format %s does not support writing %d bpp data", gbmft.short_name, gbm.bpp); } if ( (rc = gbm_read_palette(fd, ft_src, &gbm, gbmrgb)) != GBM_ERR_OK ) { gbm_io_close(fd); fatal("can't read palette of %s: %s", fn_src, gbm_err(rc)); } stride_src = ( ((gbm.w * gbm.bpp + 31)/32) * 4 ); bytes = stride_src * gbm.h; if ( (data = gbmmem_malloc(bytes)) == NULL ) { gbm_io_close(fd); #if (ULONG_MAX > UINT_MAX) fatal("out of memory allocating %zu bytes for bitmap", bytes); #else fatal("out of memory allocating %u bytes for bitmap", bytes); #endif } if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK ) { gbm_io_close(fd); fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc)); } gbm_io_close(fd); gbm_subrectangle(&gbm, x, y, w, h, data, data); if ( (fd = gbm_io_create(fn_dst, GBM_O_WRONLY)) == -1 ) fatal("can't create %s", fn_dst); gbm.w = w; gbm.h = h; if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm, gbmrgb, data, opt_dst)) != GBM_ERR_OK ) { gbm_io_close(fd); remove(fn_dst); fatal("can't write %s: %s", fn_dst, gbm_err(rc)); } gbm_io_close(fd); gbmmem_free(data); gbm_deinit(); return 0; }