home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / pcx2pxo.tproj / pcxbmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-29  |  4.7 KB  |  218 lines

  1. /*
  2.     pcxbmap.c
  3. */
  4. #include <stdio.h>
  5. #include <libc.h>
  6.  
  7. #include "pcx.h"
  8.  
  9. static unsigned char *ImgBuffer, *ImgPtr;
  10.  
  11. static unsigned char *getAllImage(FILE *fp, pcxHeader *ph, int *err)
  12. {
  13.     int    cc, n;
  14.     unsigned char *buf;
  15.  
  16.     *err = 0;
  17.     n = ph->xbytes * ph->y * ph->planes;
  18.     if ((ImgBuffer = buf = (unsigned char *)malloc(n)) == NULL) {
  19.         *err = Err_MEMORY;
  20.         return NULL;
  21.     }
  22.     /* ¥⁄¥Æ¡…¥‚⁄ù¥Æ¥í¥Œ˘í⁄¸˘²⁄ë„⁄ú⁄˙⁄•⁄ê⁄ƒ */
  23.     fseek(fp, sizeof_pcxHeader, SEEK_SET);
  24.     if (ph->comp == 1) { /* Run-Length Encoded */
  25.         while (n > 0) {
  26.             if ((cc = getc(fp)) == EOF) {
  27.                 *err = Err_SHORT;
  28.                 break;
  29.             }
  30.             if ((cc & 0xc0) == 0xc0) { /* RLE */
  31.                 int k = cc & 0x3f;
  32.                 cc = getc(fp);
  33.                 if (k > n) k = n;
  34.                 n -= k;
  35.                 while (k-- > 0)
  36.                     *buf++ = cc;
  37.             }else {
  38.                 *buf++ = cc;
  39.                 n--;
  40.             }
  41.         }
  42.     }else { /* normal */
  43.         while (n-- > 0) {
  44.             if ((cc = getc(fp)) == EOF) {
  45.                 *err = Err_SHORT;
  46.                 break;
  47.             }
  48.             *buf++ = cc;
  49.         }
  50.     }
  51.     return ImgBuffer;
  52. }
  53.  
  54. static unsigned char *conv1to8(pcxHeader *ph, unsigned char *raw)
  55.      /*    £–¥½¥ˆ¥¨¡ë£·¥â¥ò¡…¥ú⁄˛¥⁄¥Æ¡…¥‚⁄ù¡¢£‚¥½¥ˆ¥¨¡ë£–¥â¥ò¡…¥ú⁄˛•ˋ…®⁄¸
  56.     ˚±·„⁄„⁄º¡£‚«⁄«⁄–⁄ˇ 8dots/byte⁄¹⁄‹¡¢…´”é⁄ˇ£·¥²¥ˆ¥¨⁄”⁄˜¡£
  57.     ®œ¿û⁄˛ raw⁄ˇ†ù˚þ⁄¦⁄ò¡¢¿•⁄•⁄⁄¥Æ¥í¥Œ˛˛®Ł⁄‹⁄¨⁄Ø⁄ò⁄º¡£ */
  58. {
  59.     int x, y, v, mask;
  60.     unsigned char *buffer, *src;
  61.  
  62.     buffer = (unsigned char *)malloc(ph->x * ph->y + 16);
  63.         /* ph->xbytes := (ph->x + 15) / 8,
  64.          * so, 15 bytes are added for loops below. Tricky... */
  65.     if (buffer == NULL) {
  66.         free((void *)raw);
  67.         return NULL;
  68.     }
  69.  
  70.     src = raw;
  71.     for (y = 0; y < ph->y; y++) {
  72.         unsigned char *dst, *dy;
  73.         dy = &buffer[ph->x * y];
  74.         bzero(dy, ph->xbytes);
  75.         for (mask = 0x01; mask <= 0x08; mask <<= 1) {
  76.             dst = dy;
  77.             for (x = 0; x < ph->xbytes; x++) {
  78.                 for (v = 0x80; v; v >>= 1) {
  79.                     if (src[x] & v)
  80.                         *dst |= mask;
  81.                     dst++;
  82.                 }
  83.             }
  84.             src += ph->xbytes;
  85.         }
  86.     }
  87.     ph->xbytes = ph->x;
  88.     ph->bits = 8;
  89.     ph->planes = 1;
  90.     free((void *)raw);
  91.     return buffer;
  92. }
  93.  
  94. static void get2bitLine(unsigned char *line, int xbytes)
  95. {
  96.     int x, s;
  97.  
  98.     for (x = 0; x < xbytes; x++) {
  99.         for (s = 6; s >= 0; s -= 2)
  100.             *line++ = (*ImgPtr >> s) & 0x03;
  101.         ImgPtr++;
  102.     }
  103. }
  104.  
  105. static void get4bitLine(unsigned char *line, int xbytes)
  106. {
  107.     int x;
  108.     for (x = 0; x < xbytes; x++) {
  109.         *line++ = *ImgPtr >> 4;
  110.         *line++ = *ImgPtr++ & 0x0f;
  111.     }
  112. }
  113.  
  114. static void get8bitLine(unsigned char *line, int xbytes)
  115. {
  116.     int x;
  117.     for (x = 0; x < xbytes; x++)
  118.         *line++ = *ImgPtr++;
  119. }
  120.  
  121. static void writeBitmap(FILE *fw, pcxHeader *ph, unsigned char *bm)
  122. {
  123.     int x, y, width;
  124.     unsigned char *p;
  125.  
  126.     /* PBM */
  127.     fprintf(fw, "P4\n#%s\n", ph->memo);
  128.     fprintf(fw, "%d %d\n", ph->x, ph->y);
  129.     width = (ph->x + 7) >> 3;
  130.     for (y = 0; y < ph->y; y++) {
  131.         p = bm + ph->xbytes * y;
  132.         for (x = 0; x < width; x++)
  133.             putc(p[x] ^ 0xff, fw);
  134.     }
  135. }
  136.  
  137. int pcxGetImage(FILE *fp, FILE *fw, pcxHeader *ph)
  138. {
  139.     int    i, y;
  140.     int    colors, err = 0, colbit = 8;
  141.     BOOL    isgray;
  142.     paltype    *pal;
  143.     unsigned char line[MAXWidth];
  144.     void (*getNbitLine)(unsigned char *, int) = get8bitLine;
  145.  
  146.     pal = ph->palette;
  147.     if ((ImgPtr = getAllImage(fp, ph, &err)) == NULL)
  148.         return err;
  149.     /* 8bit color ⁄˛¬ò„ñ¡¢¥⁄¥Æ¡…¥‚⁄˛‚ï⁄ó⁄¸¥±¥ò¥ˆ¥¨⁄‹⁄¢⁄º */
  150.     if (ph->bits == 8 && err == 0) {
  151.         if (getc(fp) == hasPALETTE) { /* Magic Number */
  152.             if (ph->palette) free((void *)ph->palette);
  153.             pal = (paltype *)malloc(sizeof(paltype) * numPALETTE);
  154.             if (pal == NULL)
  155.                 return Err_MEMORY;
  156.             ph->palette = pal;
  157.             for (i = 0; i < numPALETTE; i++) {
  158.                 unsigned char *p = pal[i];
  159.                 if (feof(fp)) {
  160.                     err = Err_SHORT;
  161.                     break;
  162.                 }
  163.                 p[RED] = getc(fp);
  164.                 p[GREEN] = getc(fp);
  165.                 p[BLUE] = getc(fp);
  166.             }
  167.         }else
  168.             err = Err_SHORT;
  169.     }
  170.     colors = 1 << (ph->bits * ph->planes);
  171.     colbit = howManyBits(pal, colors);
  172.     isgray = isGray(pal, colors);
  173.  
  174.     if (ph->bits == 1) {
  175.         if (ph->planes == 1) { /* Monochrome */
  176.             writeBitmap(fw, ph, ImgBuffer);
  177.             return err;
  178.         }
  179.         /* 1bit x 4planes -> 8bits x 1plane */
  180.         if ((ImgBuffer = conv1to8(ph, ImgBuffer)) == NULL)
  181.             return Err_MEMORY;
  182.         ImgPtr = ImgBuffer;
  183.     }
  184.     if (ph->bits == 2)
  185.         getNbitLine = get2bitLine;
  186.     else if (ph->bits == 4)
  187.         getNbitLine = get4bitLine;
  188.     else /* 8 */
  189.         getNbitLine = get8bitLine;
  190.  
  191.     if (isgray) {
  192.         /* PGM */
  193.         fprintf(fw, "P5\n#%s\n", ph->memo);
  194.         fprintf(fw, "%d %d 255\n", ph->x, ph->y);
  195.         for (y = 0; y < ph->y; y++) {
  196.             getNbitLine(line, ph->xbytes);
  197.             for (i = 0; i < ph->x; i++)
  198.                 putc(pal[line[i]][0], fw);
  199.         }
  200.     }else {
  201.         /* PXOF: PPM eXtended Original Format */
  202.         fprintf(fw, "PX\n#%s\n", ph->memo);
  203.         fprintf(fw, "%d %d %d\n", ph->x, ph->y, colors - 1);
  204.         for (y = 0; y < colors; y++) {
  205.             unsigned char *p = pal[y];
  206.             for (i = 0; i < 3; i++)
  207.                 putc(p[i], fw);
  208.         }
  209.         for (y = 0; y < ph->y; y++) {
  210.             getNbitLine(line, ph->xbytes);
  211.             for (i = 0; i < ph->x; i++)
  212.                 putc(line[i], fw);
  213.         }
  214.     }
  215.     (void)free((void *)ImgBuffer);
  216.     return err;
  217. }
  218.