home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / sunraster.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  8KB  |  369 lines

  1. /* sunraster.c:
  2.  *
  3.  * sun rasterfile image type
  4.  *
  5.  * jim frost 09.27.89
  6.  *
  7.  * Copyright 1989, 1991 Jim Frost.
  8.  * See included file "copyright.h" for complete copyright information.
  9.  */
  10.  
  11. #include "copyright.h"
  12. #include "image.h"
  13. #include "sunraster.h"
  14.  
  15. /* SUPPRESS 558 */
  16. /* SUPPRESS 560 */
  17.  
  18. static void babble(name, header)
  19.      char           *name;
  20.      struct rheader *header;
  21. {
  22.   printf("%s is a", name);
  23.   switch (memToVal(header->type, 4)) {
  24.   case ROLD:
  25.     printf("n old-style");
  26.     break;
  27.   case RSTANDARD:
  28.     printf(" standard");
  29.     break;
  30.   case RRLENCODED:
  31.     printf(" run-length encoded");
  32.     break;
  33.   case RRGB:
  34.     printf(" RGB"); /* RGB format instead of BGR */
  35.     break;
  36.   case RTIFF:
  37.     printf(" TIFF");
  38.     break;
  39.   case RIFF:
  40.     printf(" RIFF");
  41.     break;
  42.   default:
  43.     printf(" unknown-type");
  44.   }
  45.   printf(" %dx%d", memToVal(header->width, 4), memToVal(header->height, 4));
  46.  
  47.   switch (memToVal(header->depth, 4)) {
  48.   case 1:
  49.     printf(" monochrome");
  50.     break;
  51.   case 8:
  52.     printf(" 8 plane %s",
  53.        memToVal(header->maplen, 4) > 0 ? "color" : "greyscale");
  54.     break;
  55.   case 24:
  56.     printf(" 24 plane color");
  57.     break;
  58.  
  59.   case 32:
  60.     /* isn't it nice how the sunraster.h file doesn't bother to mention that
  61.      * 32-bit depths are allowed?
  62.      */
  63.     printf(" 32 plane color");
  64.     break;
  65.   }
  66.   printf(" Sun rasterfile\n");
  67. }
  68.  
  69. int sunRasterIdent(fullname, name)
  70.      char *fullname, *name;
  71. { ZFILE          *zf;
  72.   struct rheader  header;
  73.   int             r;
  74.  
  75.   if (! (zf= zopen(fullname))) {
  76.     perror("sunRasterIdent");
  77.     return(0);
  78.   }
  79.   switch (zread(zf, (byte *)&header, sizeof(struct rheader))) {
  80.   case -1:
  81.     perror("sunRasterIdent");
  82.     r= 0;
  83.     break;
  84.  
  85.   case sizeof(struct rheader):
  86.     if (memToVal(header.magic, 4) != RMAGICNUMBER) {
  87.       r= 0;
  88.       break;
  89.     }
  90.     babble(name, &header);
  91.     r= 1;
  92.     break;
  93.  
  94.   default:
  95.     r= 0;
  96.     break;
  97.   }
  98.   zclose(zf);
  99.   return(r);
  100. }
  101.  
  102. /* read either rl-encoded or normal image data
  103.  */
  104.  
  105. static void sunread(zf, buf, len, enc)
  106.      ZFILE        *zf;
  107.      byte         *buf;
  108.      unsigned int  len;
  109.      unsigned int  enc;  /* true if encoded file */
  110. { static byte repchar, remaining= 0;
  111.  
  112.   /* rl-encoded read
  113.    */
  114.  
  115.   if (enc) {
  116.     while (len--)
  117.       if (remaining) {
  118.     remaining--;
  119.     *(buf++)= repchar;
  120.       }
  121.       else {
  122.     if (zread(zf, &repchar, 1) != 1) {
  123.       printf("sunRasterLoad: Bad read on image data\n");
  124.       exit(1);
  125.     }
  126.     if (repchar == RESC) {
  127.       if (zread(zf, &remaining, 1) != 1) {
  128.         printf("sunRasterLoad: Bad read on image data\n");
  129.         exit(1);
  130.       }
  131.       if (remaining == 0)
  132.         *(buf++)= RESC;
  133.       else {
  134.         if (zread(zf, &repchar, 1) != 1) {
  135.           printf("sunRasterLoad: Bad read on image data\n");
  136.           exit(1);
  137.         }
  138.         *(buf++)= repchar;
  139.       }
  140.     }
  141.     else
  142.       *(buf++)= repchar;
  143.       }
  144.   }
  145.  
  146.   /* normal read
  147.    */
  148.  
  149.   else {
  150.     if (zread(zf, buf, len) < len) {
  151.       printf("sunRasterLoad: Bad read on image data\n");
  152.       exit(1);
  153.     }
  154.   }
  155. }
  156.  
  157. Image *sunRasterLoad(fullname, name, verbose)
  158.      char         *fullname, *name;
  159.      unsigned int  verbose;
  160. { ZFILE          *zf;
  161.   struct rheader  header;
  162.   unsigned int    mapsize;
  163.   byte           *map;
  164.   byte           *mapred, *mapgreen, *mapblue;
  165.   unsigned int    depth;
  166.   unsigned int    linelen;   /* length of raster line in bytes */
  167.   unsigned int    fill;      /* # of fill bytes per raster line */
  168.   unsigned int    enc;
  169.   unsigned int    rgb_format;
  170.   byte            fillchar;
  171.   Image          *image;
  172.   byte           *lineptr;
  173.   unsigned int    x, y;
  174.  
  175.   if (! (zf= zopen(fullname))) {
  176.     perror("sunRasterLoad");
  177.     return(NULL);
  178.   }
  179.   switch (zread(zf, (byte *)&header, sizeof(struct rheader))) {
  180.   case -1:
  181.     perror("sunRasterLoad");
  182.     zclose(zf);
  183.     exit(1);
  184.  
  185.   case sizeof(struct rheader):
  186.     if (memToVal(header.magic, 4) != RMAGICNUMBER) {
  187.       zclose(zf);
  188.       return(NULL);
  189.     }
  190.     if (verbose)
  191.       babble(name, &header);
  192.     break;
  193.  
  194.   default:
  195.     zclose(zf);
  196.     return(NULL);
  197.   }
  198.  
  199.   znocache(zf); /* turn off caching; we don't need it anymore */
  200.  
  201.   /* get an image to put the data in
  202.    */
  203.  
  204.   depth= memToVal(header.depth, 4);
  205.   switch(depth) {
  206.   case 1:
  207.     image= newBitImage(memToVal(header.width, 4),
  208.                memToVal(header.height, 4));
  209.     break;
  210.   case 8:
  211.     image= newRGBImage(memToVal(header.width, 4),
  212.                memToVal(header.height, 4),
  213.                memToVal(header.depth, 4));
  214.     break;
  215.   case 24:
  216.   case 32:
  217.     image= newTrueImage(memToVal(header.width, 4),
  218.                memToVal(header.height, 4));
  219.     break;
  220.   default:
  221.     printf("sunRasterLoad: Bad depth %d (only 1, 8, 24 are valid)\n", depth);
  222.     exit(1);
  223.   }
  224.  
  225.   /* figure out which format it is
  226.    */
  227.  
  228.   enc= 0;
  229.   rgb_format= 0;
  230.   switch (memToVal(header.type, 4)) {
  231.   case ROLD:
  232.   case RSTANDARD:
  233.     break;
  234.   case RRLENCODED:
  235.     enc= 1;
  236.     break;
  237.   case RRGB:
  238.     rgb_format= 1;
  239.     break;
  240.   case RTIFF: /* sorry, don't even know what these are */
  241.   case RIFF:
  242.   default:
  243.     fprintf(stderr, "%s: Unsupported Sun Rasterfile image type (sorry)\n");
  244.     return(NULL);
  245.   }
  246.  
  247.   /* set up the colormap
  248.    */
  249.  
  250.   if (depth == 1)
  251.     linelen= (image->width / 8) + (image->width % 8 ? 1 : 0);
  252.   else
  253.     linelen= image->width * image->pixlen;
  254.   fill= (linelen % 2 ? 1 : 0);
  255.   /*
  256.    *  Handle color...
  257.    */
  258.   if (mapsize= memToVal(header.maplen, 4)) {
  259.     map= lmalloc(mapsize);
  260.     if (zread(zf, map, mapsize) < mapsize) {
  261.       printf("sunRasterLoad: Bad read on colormap\n");
  262.       exit(1);
  263.     }
  264.     mapsize /= 3;
  265.     mapred= map;
  266.     mapgreen= mapred + mapsize;
  267.     mapblue= mapgreen + mapsize;
  268.     if (image->rgb.size == 0)
  269.     newRGBMapData(&image->rgb, mapsize);
  270.     else if (mapsize > image->rgb.size)
  271.     mapsize= image->rgb.size;
  272.     for (y= 0; y < mapsize; y++) {
  273.       *(image->rgb.red + y)= (*(mapred++) << 8);
  274.       *(image->rgb.green + y)= (*(mapgreen++) << 8);
  275.       *(image->rgb.blue + y)= (*(mapblue++) << 8);
  276.     }
  277.     lfree(map);
  278.     image->rgb.used= mapsize;
  279.   }
  280.  
  281.   /*
  282.    *  Handle 8-bit greyscale via a simple ramp function...
  283.    */
  284.   else if (depth == 8) {
  285.     mapsize = 256*3;
  286.     map= lmalloc(mapsize);
  287.     for (y = 0; y < 256; y += 1) {
  288.       map[y] = map[256+y] = map[2*256+y] = y;
  289.     }
  290.     mapsize /= 3;
  291.     mapred= map;
  292.     mapgreen= mapred + mapsize;
  293.     mapblue= mapgreen + mapsize;
  294.     if (image->rgb.size == 0)
  295.     newRGBMapData(&image->rgb, mapsize);
  296.     for (y= 0; y < mapsize; y++) {
  297.       *(image->rgb.red + y)= (*(mapred++) << 8);
  298.       *(image->rgb.green + y)= (*(mapgreen++) << 8);
  299.       *(image->rgb.blue + y)= (*(mapblue++) << 8);
  300.     }
  301.     lfree(map);
  302.     image->rgb.used= mapsize;
  303.   }
  304.   /* 24-bit and 32-bit handle themselves.  currently we don't support
  305.    * a colormap for them.
  306.    */
  307.  
  308.   lineptr= image->data;
  309.  
  310.   /* if it's a 32-bit image, we read the line and then strip off the
  311.    * top byte of each pixel to get truecolor format
  312.    */
  313.  
  314.   if (depth >= 24) {
  315.     byte *buf, *bp;
  316.  
  317.     buf= lmalloc(image->width * (depth == 24 ? 3 : 4));
  318.     for (y= 0; y < image->height; y++) {
  319.       sunread(zf, buf, image->width * (depth == 24 ? 3 : 4), enc);
  320.       bp= buf;
  321.       if (depth == 24) {
  322.     if (rgb_format)
  323.       for (x= 0; x < image->width; x++) {
  324.         *(lineptr++)= *(bp++); /* red */
  325.         *(lineptr++)= *(bp++); /* green */
  326.         *(lineptr++)= *(bp++); /* blue */
  327.       }
  328.     else
  329.       for (x= 0; x < image->width; x++) {
  330.         *(lineptr++)= *(bp + 2); /* red */
  331.         *(lineptr++)= *(bp + 1); /* green */
  332.         *(lineptr++)= *bp;       /* blue */
  333.         bp += 3;
  334.       }
  335.       }
  336.       else {
  337.     if (rgb_format)
  338.       for (x= 0; x < image->width; x++) {
  339.         bp++;                  /* skip byte */
  340.         *(lineptr++)= *(bp++); /* red */
  341.         *(lineptr++)= *(bp++); /* green */
  342.         *(lineptr++)= *(bp++); /* blue */
  343.       }
  344.     else
  345.       for (x= 0; x < image->width; x++) {
  346.         *(lineptr++)= *(bp + 3); /* red */
  347.         *(lineptr++)= *(bp + 2); /* green */
  348.         *(lineptr++)= *(bp + 1); /* blue */
  349.         bp += 4;
  350.       }
  351.       }
  352.       if (fill)
  353.     sunread(zf, &fillchar, fill, enc);
  354.     }
  355.     lfree(buf);
  356.   }
  357.   else {
  358.     for (y= 0; y < image->height; y++) {
  359.       sunread(zf, lineptr, linelen, enc);
  360.       lineptr += linelen;
  361.       if (fill)
  362.     sunread(zf, &fillchar, fill, enc);
  363.     }
  364.   }
  365.   zclose(zf);
  366.   image->title= dupString(name);
  367.   return(image);
  368. }
  369.