/*...sLoadBitmap:0:*/ static BOOL LoadBitmap( HWND hwnd, const CHAR *szFn, const CHAR *szOpt, GBM *gbm, GBMRGB *gbmrgb, BYTE **ppbData ) { GBM_ERR rc; int fd, ft; ULONG cb; USHORT usStride; if ( gbm_guess_filetype(szFn, &ft) != GBM_ERR_OK ) { Warning(hwnd, "Can't deduce bitmap format from file extension: %s", szFn); return ( FALSE ); } if ( (fd = open(szFn, O_RDONLY | O_BINARY)) == -1 ) { Warning(hwnd, "Can't open file: %s", szFn); return ( FALSE ); } if ( (rc = gbm_read_header(szFn, fd, ft, gbm, szOpt)) != GBM_ERR_OK ) { close(fd); Warning(hwnd, "Can't read file header of %s: %s", szFn, gbm_err(rc)); return ( FALSE ); } if ( (rc = gbm_read_palette(fd, ft, gbm, gbmrgb)) != GBM_ERR_OK ) { close(fd); Warning(hwnd, "Can't read file palette of %s: %s", szFn, gbm_err(rc)); return ( FALSE ); } usStride = ((gbm -> w * gbm -> bpp + 31)/32) * 4; cb = gbm -> h * usStride; if ( (*ppbData = malloc((int) cb)) == NULL ) { close(fd); Warning(hwnd, "Out of memory requesting %ld bytes", cb); return ( FALSE ); } if ( (rc = gbm_read_data(fd, ft, gbm, *ppbData)) != GBM_ERR_OK ) { free(*ppbData); close(fd); Warning(hwnd, "Can't read file data of %s: %s", szFn, gbm_err(rc)); return ( FALSE ); } close(fd); return ( TRUE ); }
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; }
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; }
int main(int argc, char *argv[]) { char fn_src[500+1], fn_dst[500+1], *opt_src, *opt_dst; int fd, ft_src, ft_dst, i, stride, bytes, flag, m; GBM_ERR rc; GBMFT gbmft; GBM gbm; GBMRGB gbmrgb[0x100]; byte *data; char *map = "none"; byte remap[0x100]; double gam = 2.1, shelf = 0.0; /*...scommand line arguments:8:*/ for ( i = 1; i < argc; i++ ) { if ( argv[i][0] != '-' ) break; switch ( argv[i][1] ) { case 'm': if ( ++i == argc ) fatal("expected map argument"); map = argv[i]; break; case 'g': if ( ++i == argc ) usage(); gam = get_opt_double(argv[i], "gam"); if ( gam < 0.1 || gam > 10.0 ) fatal("only gammas in the range 0.1 to 10.0 are sensible"); break; case 's': if ( ++i == argc ) usage(); shelf = get_opt_double(argv[i], "shelf"); break; default: usage(); break; } } /*...e*/ /*...sdeduce mapping and bits per pixel etc\46\:8:*/ { int j; for ( j = 0; j < N_MAPINFOS; j++ ) if ( same(map, mapinfos[j].name, strlen(map) + 1) ) break; if ( j == N_MAPINFOS ) fatal("unrecognised mapping %s", map); m = mapinfos[j].m; } /*...e*/ if ( i == argc ) usage(); strcpy(fn_src, argv[i++]); strcpy(fn_dst, ( i == argc ) ? fn_src : argv[i++]); if ( i < argc ) usage(); if ( (opt_src = strchr(fn_src, ',')) != NULL ) *opt_src++ = '\0'; else opt_src = ""; if ( (opt_dst = strchr(fn_dst, ',')) != NULL ) *opt_dst++ = '\0'; else opt_dst = ""; 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 = open(fn_src, O_RDONLY | O_BINARY)) == -1 ) fatal("can't open %s", fn_src); if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK ) { close(fd); fatal("can't read header of %s: %s", fn_src, gbm_err(rc)); } 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 ) { 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 ) { close(fd); fatal("can't read palette of %s: %s", fn_src, gbm_err(rc)); } stride = ( ((gbm.w * gbm.bpp + 31)/32) * 4 ); bytes = stride * gbm.h; if ( (data = malloc(bytes)) == NULL ) { close(fd); fatal("out of memory allocating %d bytes for bitmap", bytes); } if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK ) { close(fd); fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc)); } close(fd); map_compute(m, remap, gam, shelf); if ( gbm.bpp == 24 ) map_data(data, gbm.w, gbm.h, remap); else map_palette(gbmrgb, 1 << gbm.bpp, remap); if ( (fd = open(fn_dst, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1 ) fatal("can't create %s", fn_dst); if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm, gbmrgb, data, opt_dst)) != GBM_ERR_OK ) { close(fd); remove(fn_dst); fatal("can't write %s: %s", fn_dst, gbm_err(rc)); } 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; }