home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gbmsrc.zip / gbmsub.c < prev    next >
C/C++ Source or Header  |  1998-12-31  |  6KB  |  257 lines

  1. /*
  2.  
  3. gbmsub.c - Subrectangle of General Bitmap
  4.  
  5. */
  6.  
  7. /*...sincludes:0:*/
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <stdarg.h>
  14. #include <memory.h>
  15. #include <malloc.h>
  16. #if defined(AIX) || defined(LINUX)
  17. #include <unistd.h>
  18. #else
  19. #include <io.h>
  20. #endif
  21. #include <fcntl.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #ifndef O_BINARY
  25. #define    O_BINARY    0
  26. #endif
  27. #include "gbm.h"
  28. #include "gbmrect.h"
  29.  
  30. /*...vgbm\46\h:0:*/
  31. /*...vgbmrect\46\h:0:*/
  32. /*...e*/
  33.  
  34. static char progname[] = "gbmsub";
  35.  
  36. /*...sfatal:0:*/
  37. static void fatal(const char *fmt, ...)
  38.     {
  39.     va_list    vars;
  40.     char s[256+1];
  41.  
  42.     va_start(vars, fmt);
  43.     vsprintf(s, fmt, vars);
  44.     va_end(vars);
  45.     fprintf(stderr, "%s: %s\n", progname, s);
  46.     exit(1);
  47.     }
  48. /*...e*/
  49. /*...susage:0:*/
  50. static void usage(void)
  51.     {
  52.     int ft, n_ft;
  53.  
  54.     fprintf(stderr, "usage: %s [-x x] [-y y] [-w w] [-h h] [--] fn1.ext{,opt} [fn2.ext{,opt}]\n", progname);
  55.     fprintf(stderr, "flags: -x x           left edge of rectangle (default 0)\n");
  56.     fprintf(stderr, "       -y y           bottom edge of rectangle (default 0)\n");
  57.     fprintf(stderr, "       -w w           width of rectangle (default width of image - x)\n");
  58.     fprintf(stderr, "       -h h           height of rectangle (default height of image - y)\n");
  59.     fprintf(stderr, "       fn1.ext{,opt}  input filename (with any format specific options)\n");
  60.     fprintf(stderr, "       fn2.ext{,opt}  optional output filename (or will use fn1 if not present)\n");
  61.     fprintf(stderr, "                      ext's are used to deduce desired bitmap file formats\n");
  62.  
  63.     gbm_init();
  64.     gbm_query_n_filetypes(&n_ft);
  65.     for ( ft = 0; ft < n_ft; ft++ )
  66.         {
  67.         GBMFT gbmft;
  68.  
  69.         gbm_query_filetype(ft, &gbmft);
  70.         fprintf(stderr, "                      %s when ext in [%s]\n",
  71.             gbmft.short_name, gbmft.extensions);
  72.         }
  73.     gbm_deinit();
  74.  
  75.     fprintf(stderr, "       opt's          bitmap format specific options\n");
  76.  
  77.     exit(1);
  78.     }
  79. /*...e*/
  80. /*...sget_opt_value:0:*/
  81. static int get_opt_value(const char *s, const char *name)
  82.     {
  83.     int v;
  84.  
  85.     if ( s == NULL )
  86.         fatal("missing %s argument", name);
  87.     if ( !isdigit(s[0]) )
  88.         fatal("bad %s argument", name);
  89.     if ( s[0] == '0' && tolower(s[1]) == 'x' )
  90.         sscanf(s + 2, "%x", &v);
  91.     else
  92.         v = atoi(s);
  93.  
  94.     return v;
  95.     }
  96. /*...e*/
  97. /*...sget_opt_value_pos:0:*/
  98. static int get_opt_value_pos(const char *s, const char *name)
  99.     {
  100.     int n;
  101.  
  102.     if ( (n = get_opt_value(s, name)) < 0 )
  103.         fatal("%s should not be negative", name);
  104.     return n;
  105.     }
  106. /*...e*/
  107. /*...smain:0:*/
  108. int main(int argc, char *argv[])
  109.     {
  110.     int    x = 0, y = 0, w = -1, h = -1;
  111.     char    fn_src[500+1], fn_dst[500+1], *opt_src, *opt_dst;
  112.     int    fd, ft_src, ft_dst, i, stride_src, flag, bytes;
  113.     GBM_ERR    rc;
  114.     GBMFT    gbmft;
  115.     GBM    gbm;
  116.     GBMRGB    gbmrgb[0x100];
  117.     byte    *data;
  118.  
  119.     for ( i = 1; i < argc; i++ )
  120.         {
  121.         if ( argv[i][0] != '-' )
  122.             break;
  123.         else if ( argv[i][1] == '-' )
  124.             { ++i; break; }
  125.         switch ( argv[i][1] )
  126.             {
  127.             case 'x':
  128.                 if ( ++i == argc ) usage();
  129.                 x = get_opt_value_pos(argv[i], "x");
  130.                 break;
  131.             case 'y':
  132.                 if ( ++i == argc ) usage();
  133.                 y = get_opt_value_pos(argv[i], "y");
  134.                 break;
  135.             case 'w':
  136.                 if ( ++i == argc ) usage();
  137.                 w = get_opt_value_pos(argv[i], "w");
  138.                 break;
  139.             case 'h':
  140.                 if ( ++i == argc ) usage();
  141.                 h = get_opt_value_pos(argv[i], "h");
  142.                 break;
  143.             default:
  144.                 usage();
  145.                 break;
  146.             }
  147.         }
  148.  
  149.     if ( i == argc )
  150.         usage();
  151.     strcpy(fn_src, argv[i++]);
  152.     strcpy(fn_dst, ( i == argc ) ? fn_src : argv[i++]);
  153.     if ( i < argc )
  154.         usage();
  155.  
  156.     if ( (opt_src = strchr(fn_src, ',')) != NULL )
  157.         *opt_src++ = '\0';
  158.     else
  159.         opt_src = "";
  160.  
  161.     if ( (opt_dst = strchr(fn_dst, ',')) != NULL )
  162.         *opt_dst++ = '\0';
  163.     else
  164.         opt_dst = "";
  165.  
  166.     gbm_init();
  167.  
  168.     if ( gbm_guess_filetype(fn_src, &ft_src) != GBM_ERR_OK )
  169.         fatal("can't guess bitmap file format for %s", fn_src);
  170.  
  171.     if ( gbm_guess_filetype(fn_dst, &ft_dst) != GBM_ERR_OK )
  172.         fatal("can't guess bitmap file format for %s", fn_dst);
  173.  
  174.     if ( (fd = gbm_io_open(fn_src, O_RDONLY|O_BINARY)) == -1 )
  175.         fatal("can't open %s", fn_src);
  176.  
  177.     if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK )
  178.         {
  179.         gbm_io_close(fd);
  180.         fatal("can't read header of %s: %s", fn_src, gbm_err(rc));
  181.         }
  182.  
  183.     if ( w == -1 )
  184.         w = gbm.w - x;
  185.  
  186.     if ( h == -1 )
  187.         h = gbm.h - y;
  188.  
  189.     if ( w     == 0     ) { gbm_io_close(fd); fatal("w = 0"); }
  190.     if ( h     == 0     ) { gbm_io_close(fd); fatal("h = 0"); }
  191.     if ( x     >= gbm.w ) { gbm_io_close(fd); fatal("x >= bitmap width"); }
  192.     if ( y     >= gbm.h ) { gbm_io_close(fd); fatal("y >= bitmap height"); }
  193.     if ( x + w >  gbm.w ) { gbm_io_close(fd); fatal("x+w > bitmap width"); }
  194.     if ( y + h >  gbm.h ) { gbm_io_close(fd); fatal("y+h > bitmap height"); }
  195.  
  196.     gbm_query_filetype(ft_dst, &gbmft);
  197.     switch ( gbm.bpp )
  198.         {
  199.         case 24:    flag = GBM_FT_W24;    break;
  200.         case 8:        flag = GBM_FT_W8;    break;
  201.         case 4:        flag = GBM_FT_W4;    break;
  202.         case 1:        flag = GBM_FT_W1;    break;
  203.         }
  204.     if ( (gbmft.flags & flag) == 0 )
  205.         {
  206.         gbm_io_close(fd);
  207.         fatal("output bitmap format %s does not support writing %d bpp data",
  208.             gbmft.short_name, gbm.bpp);
  209.         }
  210.  
  211.     if ( (rc = gbm_read_palette(fd, ft_src, &gbm, gbmrgb)) != GBM_ERR_OK )
  212.         {
  213.         gbm_io_close(fd);
  214.         fatal("can't read palette of %s: %s", fn_src, gbm_err(rc));
  215.         }
  216.  
  217.     stride_src = ( ((gbm.w * gbm.bpp + 31)/32) * 4 );
  218.     bytes = stride_src * gbm.h;
  219.     if ( (data = malloc((size_t) bytes)) == NULL )
  220.         {
  221.         gbm_io_close(fd);
  222.         fatal("out of memory allocating %d bytes for bitmap", bytes);
  223.         }
  224.  
  225.     if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK )
  226.         {
  227.         gbm_io_close(fd);
  228.         fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc));
  229.         }
  230.  
  231.     gbm_io_close(fd);
  232.  
  233.     gbm_subrectangle(&gbm, x, y, w, h, data, data);
  234.  
  235.     if ( (fd = gbm_io_create(fn_dst, O_WRONLY|O_BINARY)) == -1 )
  236.         fatal("can't create %s", fn_dst);
  237.  
  238.     gbm.w = w;
  239.     gbm.h = h;
  240.  
  241.     if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm, gbmrgb, data, opt_dst)) != GBM_ERR_OK )
  242.         {
  243.         gbm_io_close(fd);
  244.         remove(fn_dst);
  245.         fatal("can't write %s: %s", fn_dst, gbm_err(rc));
  246.         }
  247.  
  248.     gbm_io_close(fd);
  249.  
  250.     free(data);
  251.  
  252.     gbm_deinit();
  253.  
  254.     return 0;
  255.     }
  256. /*...e*/
  257.