home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 580a.lha / hdf_utilities / src.LZH / src / r24hdf8.c < prev   
Encoding:
C/C++ Source or Header  |  1991-11-11  |  10.4 KB  |  421 lines

  1. /*****************************************************************************
  2. *              NCSA HDF version 3.10r3
  3. *                Dec 6, 1990
  4. *
  5. * NCSA HDF Version 3.10r3 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************/
  16.  
  17. #ifdef RCSID
  18. static char RcsId[] = "@(#)$Revision: 1.1 $";
  19. #endif
  20. /*
  21. $Header: /pita/work/HDF/dev/RCS/src/r24hdf8.c,v 1.1 90/07/06 10:26:01 mfolk beta $
  22.  
  23. $Log:    r24hdf8.c,v $
  24.  * Revision 1.1  90/07/06  10:26:01  mfolk
  25.  * Initial revision
  26.  * 
  27. */
  28. /*
  29.   r24hdf8    Quantizes a raw RGB 24 bit "pixel" image into a 8 bit image
  30.         with RGB palette and stores it as a HDF 8-bit raster image
  31.         file.
  32.  
  33.   usage:    r24hdf8 x_dim y_dim r24_file hdf8_file
  34.  
  35.         On Input:
  36.         --------
  37.  
  38.         x_dim        - X dimension of image (horizontal size).
  39.         y_dim        - Y dimension of image (vertical size).
  40.         r24_file    - File containing the raw RGB 24
  41.                   bit image. The order of pixels is left to
  42.                   right and top to bottom. Each pixel is
  43.                   three contiguous bytes: red byte, green byte,
  44.                   and blue byte. Use filter ptox to convert
  45.                   from "planar" to "pixel" where planar means
  46.                   all red bytes for the whole image, followed 
  47.                   by all green bytes for the whole image, 
  48.                   followed by all blue bytes for the whole
  49.                   image.
  50.  
  51.         On Output:
  52.         ---------
  53.  
  54.         hdf8_file    - HDF file with one 8-bit raster image set,
  55.                   i.e. 8-bit image, dimensions, and 
  56.                   RGB palette.
  57.  
  58.   by:        NCSA
  59.   date(s):    May 89, Jun 89, Aug 89
  60.  
  61. ******************************************************************************
  62. * The following source code is in the public domain.
  63. * Specifically, we give to the public domain all rights for future licensing
  64. * of the source code, all resale rights, and all publishing rights.
  65. * We ask, but do not require, that the following message be included in all
  66. * derived works:
  67. * Portions developed at the National Center for Supercomputing Applications at
  68. * the University of Illinois at Urbana-Champaign.
  69. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  70. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  71. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  72. ******************************************************************************
  73. */
  74.  
  75. typedef    unsigned char    UCHAR;
  76. typedef unsigned int    UINT;
  77.  
  78. #define        NCOLORS        256
  79. #define        PALSIZE        3 * NCOLORS
  80. #define        COMPRESSION    0        /* no compression */
  81.  
  82. #include <stdio.h>
  83.  
  84. #ifdef UNIX
  85. #include <sys/file.h>
  86. #endif
  87. #ifdef MAC
  88. #include <FCntl.h>
  89. #include <StdLib.h>
  90. #endif
  91.  
  92. #include <hdf/df.h>
  93.  
  94. #define USAGE    fprintf (stderr, "usage: r24hdf8 x_dim y_dim r24_file hdf8_file\n")
  95.  
  96. main (argc, argv)
  97. int argc;
  98. char *argv[];
  99. {
  100.     int i, nc;
  101.     int fdr24;
  102.     int x_dim, y_dim, size;
  103.     char c;
  104.     char *ptr;
  105.     UCHAR *r24, *r8, *pal;
  106.     UCHAR hdfpal[PALSIZE], *p;
  107. #ifdef UNIX
  108.     char *malloc ();
  109. #endif
  110.  
  111.     if (argc != 5)
  112.     {
  113.         USAGE;
  114.         exit (1);
  115.     }
  116.  
  117.     x_dim = strtol (argv[1], &ptr, 10);
  118.     if (*ptr != NULL || x_dim <= 0) 
  119.     {
  120.         fprintf (stderr, "error: x dimension = %s is bad\n", argv[1]);
  121.         exit (-1);
  122.     }
  123.     y_dim = strtol (argv[2], &ptr, 10);
  124.     if (*ptr != NULL || y_dim <= 0) 
  125.     {
  126.         fprintf (stderr, "error: y dimension = %s is bad\n", argv[2]);
  127.         exit (-1);
  128.     }
  129.     size = x_dim * y_dim;
  130.  
  131.     if ((r24 = (UCHAR *) malloc (size * 3)) == NULL)
  132.     {
  133.         fprintf (stderr, "error: malloc to hold r24 image failed\n");
  134.         exit (-1);
  135.     }
  136.     if ((fdr24 = open (argv[3], "r")) == -1)
  137.     {
  138.         fprintf (stderr, "error: cannot open file %s to read\n", argv[3]);
  139.         exit (-1);
  140.     }
  141.  
  142.     if ((nc = read (fdr24, (char *) r24, size * 3)) != size * 3)
  143.     {
  144.         fprintf (stderr, "error: only %d bytes read from file %s - should be %d\n", nc, argv[3], size * 3);
  145.         exit (-1);
  146.     }
  147.         /* check for end of file */
  148.     if ((nc = read (fdr24, &c, 1)) != 0)
  149.     {
  150.         fprintf (stderr, "error: more bytes in file %s then dimensions indicate\n", argv[3]);
  151.         exit (-1);
  152.     }
  153.  
  154.     if ((r8 = (UCHAR *) malloc (size)) == NULL)
  155.     {
  156.         fprintf (stderr, "error: malloc to hold r8 image failed\n");
  157.         exit (-1);
  158.     }
  159.     if ((pal = (UCHAR *) malloc (PALSIZE)) == NULL)
  160.     {
  161.         fprintf (stderr, "error: malloc to hold palette failed\n");
  162.         exit (-1);
  163.     }
  164.  
  165.     if (r24r8 (x_dim, y_dim, r24, r8, NCOLORS, pal) == -1)
  166.     {
  167.         fprintf (stderr, "error: quantization failed\n");
  168.         exit (-1);
  169.     }
  170.  
  171.         /* rearrange palette to conform to HDF requirements */
  172.     p = hdfpal;
  173.     for (i = 0; i < NCOLORS; i++)
  174.     {
  175.         *p++ = pal[i];
  176.         *p++ = pal[i + NCOLORS];
  177.         *p++ = pal[i + NCOLORS * 2];
  178.     }
  179.     if (DFR8setpalette (hdfpal) == -1)
  180.     {
  181.         fprintf (stderr, "error: HDF set palette failed - error code = %d\n", DFerror);
  182.         exit (-1);
  183.     }
  184.     if (DFR8putimage (argv[4], r8, x_dim, y_dim, COMPRESSION) == -1)
  185.     {
  186.         fprintf (stderr, "error: HDF put image failed - error code = %d\n", DFerror);
  187.         exit (-1);
  188.     }
  189.     close (fdr24);
  190.  
  191.     free ((char *) r24);
  192.     free ((char *) r8);
  193.     free ((char *) pal);
  194.  
  195.     return 0;
  196. }
  197.  
  198. r24r8 (xres, yres, dat24, dat8, cres, cdat)
  199. int      xres;        /* x dimension - horizontal size */
  200. int      yres;        /* y dimension - vertical size */
  201. UCHAR   *dat24;        /* pointer to 24 bit image in "pixel" format */
  202. UCHAR   *dat8;        /* pointer to 8 bit image */
  203. int      cres;        /* number of colors in the palette - use 256 */
  204. UCHAR   *cdat;        /* pointer to palette - should be 3 * 256 bytes long */
  205. {
  206. /* 
  207.   by:        NCSA
  208.   date(s):    May 89, Jun 89
  209.  
  210. ******************************************************************************
  211. * The following source code is in the public domain.
  212. * Specifically, we give to the public domain all rights for future licensing
  213. * of the source code, all resale rights, and all publishing rights.
  214. * We ask, but do not require, that the following message be included in all
  215. * derived works:
  216. * Portions developed at the National Center for Supercomputing Applications at
  217. * the University of Illinois at Urbana-Champaign.
  218. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  219. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  220. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  221. ******************************************************************************
  222. */
  223.     int      ct,xct,yct;
  224.     int      rres,rd,rr,rn,rct;
  225.     int      gres,gd,gr,gn,gct;
  226.     int      bres,bd,br,bn,bct;
  227.     int      coff;
  228.     UINT    *idat[2];
  229.     UINT    *cp,*np;
  230.     UCHAR   *dip,*dop,*rp,*gp,*bp;
  231. #ifdef UNIX
  232.     char    *malloc();
  233. #endif
  234.  
  235.     if ((idat[0] = (UINT *)malloc(6*xres*sizeof(UINT))) == NULL)
  236.     {   fprintf(stderr,"error: Memory allocation fault\n");
  237.     return -1;
  238.     }
  239.     idat[1] = idat[0] + (3 * xres);
  240.  
  241.     rres = 6;
  242.     gres = 7;
  243.     bres = 6;
  244.     coff = 2;
  245.  
  246.     rr = gr = br = 255;
  247.     rn = rres - 1;
  248.     gn = gres - 1;
  249.     bn = bres - 1;
  250.  
  251.     rp = cdat + coff;
  252.     gp = rp + cres;
  253.     bp = gp + cres;
  254.  
  255.     for (rct=0; rct<rres; rct++)
  256.     {   for (gct=0; gct<gres; gct++)
  257.     {   for (bct=0; bct<bres; bct++)
  258.         {   *rp++ = (UCHAR)(rr * rct / rn);
  259.         *gp++ = (UCHAR)(gr * gct / gn);
  260.         *bp++ = (UCHAR)(br * bct / bn);
  261.         }
  262.     }
  263.     }
  264.  
  265.     rp = cdat;
  266.     gp = rp + cres;
  267.     bp = gp + cres;
  268.     cp = idat[0];
  269.     np = idat[1];
  270.     dip = dat24;
  271.     dop = dat8;
  272.  
  273.     for (xct=3*xres; --xct>=0; )
  274.     *cp++ = *dip++;
  275.  
  276.     for (yct=0; yct<(yres-1); yct++)
  277.     {
  278.     np = idat[(yct+1)%2];
  279.     for (xct=3*xres; --xct>=0; )
  280.         *np++ = *dip++;
  281.  
  282.     cp = idat[yct%2];
  283.     np = idat[(yct+1)%2];
  284.  
  285.     if ((rct = (cp[0] * rn / rr)) > rn) rct = rn;
  286.     if ((gct = (cp[1] * gn / gr)) > gn) gct = gn;
  287.     if ((bct = (cp[2] * bn / br)) > bn) bct = bn;
  288.  
  289.     *dop++ = ct = (rct * gres + gct) * bres + bct + coff;
  290.  
  291.     rd = cp[0] - rp[ct];
  292.     gd = cp[1] - gp[ct];
  293.     bd = cp[2] - bp[ct];
  294.  
  295.     cp += 3;
  296.     np += 3;
  297.  
  298.     cp[0]  += rd * 7 / 16;
  299.     cp[1]  += gd * 7 / 16;
  300.     cp[2]  += bd * 7 / 16;
  301.     np[-3] += rd * 5 / 16;
  302.     np[-2] += gd * 5 / 16;
  303.     np[-1] += bd * 5 / 16;
  304.     np[0]  += rd / 16;
  305.     np[1]  += gd / 16;
  306.     np[2]  += bd / 16;
  307.  
  308.     for (xct=2; xct<xres; xct++)
  309.     {
  310.         if ((rct = (cp[0] * rn / rr)) > rn) rct = rn;
  311.         if ((gct = (cp[1] * gn / gr)) > gn) gct = gn;
  312.         if ((bct = (cp[2] * bn / br)) > bn) bct = bn;
  313.  
  314.         *dop++ = ct = (rct * gres + gct) * bres + bct + coff;
  315.  
  316.         rd = cp[0] - rp[ct];
  317.         gd = cp[1] - gp[ct];
  318.         bd = cp[2] - bp[ct];
  319.  
  320.         cp += 3;
  321.         np += 3;
  322.  
  323.         cp[0]  += rd * 7 / 16;
  324.         cp[1]  += gd * 7 / 16;
  325.         cp[2]  += bd * 7 / 16;
  326.         np[-6] += rd * 3 / 16;
  327.         np[-5] += gd * 3 / 16;
  328.         np[-4] += bd * 3 / 16;
  329.         np[-3] += rd * 5 / 16;
  330.         np[-2] += gd * 5 / 16;
  331.         np[-1] += bd * 5 / 16;
  332.         np[0]  += rd / 16;
  333.         np[1]  += gd / 16;
  334.         np[2]  += bd / 16;
  335.  
  336.     }
  337.  
  338.     if ((rct = (cp[0] * rn / rr)) > rn) rct = rn;
  339.     if ((gct = (cp[1] * gn / gr)) > gn) gct = gn;
  340.     if ((bct = (cp[2] * bn / br)) > bn) bct = bn;
  341.  
  342.     *dop++ = ct = (rct * gres + gct) * bres + bct + coff;
  343.  
  344.     rd = cp[0] - rp[ct];
  345.     gd = cp[1] - gp[ct];
  346.     bd = cp[2] - bp[ct];
  347.  
  348.     cp += 3;
  349.     np += 3;
  350.  
  351.     np[-6] += rd * 3 / 16;
  352.     np[-5] += gd * 3 / 16;
  353.     np[-4] += bd * 3 / 16;
  354.     np[-3] += rd * 5 / 16;
  355.     np[-2] += gd * 5 / 16;
  356.     np[-1] += bd * 5 / 16;
  357.     }
  358.  
  359.     cp = idat[yct%2];
  360.  
  361.     if ((rct = (cp[0] * rn / rr)) > rn) rct = rn;
  362.     if ((gct = (cp[1] * gn / gr)) > gn) gct = gn;
  363.     if ((bct = (cp[2] * bn / br)) > bn) bct = bn;
  364.  
  365.     *dop++ = ct = (rct * gres + gct) * bres + bct + coff;
  366.  
  367.     rd = cp[0] - rp[ct];
  368.     gd = cp[1] - gp[ct];
  369.     bd = cp[2] - bp[ct];
  370.  
  371.     cp += 3;
  372.  
  373.     cp[0]  += rd * 7 / 16;
  374.     cp[1]  += gd * 7 / 16;
  375.     cp[2]  += bd * 7 / 16;
  376.  
  377.     for (xct=2; xct<xres; xct++)
  378.     {
  379.     if ((rct = (cp[0] * rn / rr)) > rn) rct = rn;
  380.     if ((gct = (cp[1] * gn / gr)) > gn) gct = gn;
  381.     if ((bct = (cp[2] * bn / br)) > bn) bct = bn;
  382.  
  383.     *dop++ = ct = (rct * gres + gct) * bres + bct + coff;
  384.  
  385.     rd = cp[0] - rp[ct];
  386.     gd = cp[1] - gp[ct];
  387.     bd = cp[2] - bp[ct];
  388.  
  389.     cp += 3;
  390.  
  391.     cp[0]  += rd * 7 / 16;
  392.     cp[1]  += gd * 7 / 16;
  393.     cp[2]  += bd * 7 / 16;
  394.     }
  395.  
  396.     if ((rct = (cp[0] * rn / rr)) > rn) rct = rn;
  397.     if ((gct = (cp[1] * gn / gr)) > gn) gct = gn;
  398.     if ((bct = (cp[2] * bn / br)) > bn) bct = bn;
  399.  
  400.     *dop++ = (rct * gres + gct) * bres + bct + coff;
  401.  
  402.     free(idat[0]);
  403.     return 0;
  404. }
  405.  
  406.