home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / REND.LZH / PIC1600 / F_16_16.C next >
C/C++ Source or Header  |  1996-06-12  |  12KB  |  427 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <string.h>
  4. #include    "piclib.h"
  5. #ifndef SEEK_SET
  6.     #define SEEK_SET 0
  7. #endif
  8.  
  9. extern PicFunction PicFunction_25_7;
  10.  
  11. typedef struct {
  12.     FILE *fp;
  13.     unsigned short buffer[BUFFERSIZE];
  14.     Pixel *pixelbuffer;
  15.     unsigned int seek;
  16.     unsigned long totallength;
  17.     unsigned int nowpoint;
  18.     unsigned short nowcolor;
  19.     unsigned short nowlength;
  20.     PicReduceData *reduce;
  21. }    PicWork;
  22.  
  23. #ifdef LittleEndian
  24. #define r_short(p)        (((unsigned char*)(p))[0] * 256 + ((unsigned char*)(p))[1])
  25. #define w_short(p,n)    ((((unsigned char*)(p))[0] = (n)/256), (((unsigned char*)(p))[1] = (n)%256))
  26. #else
  27. #define r_short(p)         (*((unsigned short *)(p)))
  28. #define w_short(p,n)    ((*((unsigned short *)(p))) = n)
  29. #endif
  30.  
  31. static INLINE int    getshort(FILE *fp)
  32. {
  33.     int i;
  34.     i = fgetc(fp) * 256;
  35.     i += fgetc(fp);
  36.     return i;
  37. }
  38.  
  39. static INLINE long getlong(FILE *fp)
  40. {
  41.     long i;
  42.     i = getshort(fp) * 65536L;
  43.     i += getshort(fp);
  44.     return i;
  45. }
  46.  
  47. int    WritePicHeader_DPIC(PicHeader *ph, FILE *fp)
  48. {
  49.     int i;
  50.     fprintf(fp, "image\r\n");
  51.     fprintf(fp, "mod %s\r\n", compresstoken[ph->mode]);
  52.     fprintf(fp, "pxn %d %d\r\n", ph->pixelX, ph->pixelY);
  53.     fprintf(fp, "pxs %d %d\r\n", ph->screenX, ph->screenY);
  54.     fprintf(fp, "pnt %d %d\r\n", ph->positionX, ph->positionY);
  55.     fprintf(fp, "frm %d\r\n", ph->frame);
  56.     fprintf(fp, "cst {\r\n");
  57.     for (i = 0; ph->storecolor[i] != 0; ++i) {
  58.         fprintf(fp, "%s %d\r\n", colortoken[ph->storecolor[i]], ph->storecolorbit[i]);
  59.     }
  60.     fprintf(fp, "}\r\ndst {\r\n");
  61.     for (i = 0; ph->storedata[i] != 0; ++i) {
  62.         fprintf(fp, "%s %d\r\n", datatoken[ph->storedata[i]], ph->storedatabit[i]);
  63.     }
  64.     fprintf(fp, "}\r\n\x1a");
  65.     if (ferror(fp)) return FALSE;
  66.     return TRUE;
  67. }
  68.  
  69. int        PicReadHeader_DPIC(PicHeader *ph, FILE *fp)
  70. {
  71.     extern char    *GetToken(char *buf, FILE *fp);
  72.     extern int    GetIdentifier(char *string, char *select[]);
  73.  
  74.     int i, j;
  75.     char    str[STRING];
  76.     if (GetToken(str, fp) == NULL || strcmp(str, "image")) {
  77.         return FALSE;
  78.     }
  79.     ph->storecolor[0] = 0;
  80.     ph->storedata[0] = 0;
  81.     while (GetToken(str, fp) != NULL) {
  82.         if (ferror(fp)) return FALSE;
  83.         if (str[0] == EOFCODE) {
  84.             j = 0;
  85.             for (i = 0; ph->storecolor[i] != 0; ++i) {
  86.                 j += ph->storecolorbit[i];
  87.             }
  88.             ph->colorbytes = (j - 1) / 8 + 1;
  89.             j = 0;
  90.             for (i = 0; ph->storedata[i] != 0; ++i) {
  91.                 j += ph->storedatabit[i];
  92.             }
  93.             ph->databytes = (j - 1) / 8 + 1;
  94.             return TRUE;
  95.         } else if (i = GetIdentifier(str, identtoken), i != 0) {
  96.             switch(i) {
  97.             case MOD :
  98.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  99.                     return FALSE;
  100.                 }
  101.                 i = GetIdentifier(str, compresstoken);
  102.                 if (i != 0) {
  103.                     ph->mode = i;
  104.                 } else {
  105.                     return FALSE;
  106.                 }
  107.                 break;
  108.             case PXN :
  109.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  110.                     return FALSE;
  111.                 }
  112.                 ph->pixelX = atoi(str);
  113.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  114.                     return FALSE;
  115.                 }
  116.                 ph->pixelY = atoi(str);
  117.                 break;
  118.             case PXS :
  119.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  120.                     return FALSE;
  121.                 }
  122.                 ph->screenX = atoi(str);
  123.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  124.                     return FALSE;
  125.                 }
  126.                 ph->screenY = atoi(str);
  127.                 break;
  128.             case PNT :
  129.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  130.                     return FALSE;
  131.                 }
  132.                 ph->positionX = atoi(str);
  133.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  134.                     return FALSE;
  135.                 }
  136.                 ph->positionY = atoi(str);
  137.                 break;
  138.             case FRM :
  139.                 if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
  140.                     return FALSE;
  141.                 }
  142.                 ph->frame = atoi(str);
  143.                 break;
  144.             case CST :
  145.                 if (GetToken(str, fp) == NULL || str[0] != '{') {
  146.                     return FALSE;
  147.                 }
  148.                 j = 0;
  149.                 while (GetToken(str, fp) != NULL && str[0] != EOFCODE && str[0] != '}') {
  150.                     i = GetIdentifier(str, colortoken);
  151.                     if (i == 0) {
  152.                         break;
  153.                     }
  154.                     ph->storecolor[j] = i;
  155.                     if (GetToken(str, fp) == NULL || str[0] == EOFCODE || str[0] == '}') {
  156.                         break;
  157.                     }
  158.                     ph->storecolorbit[j++] = atoi(str);
  159.                 }
  160.                 if (str[0] != '}') {
  161.                     return FALSE;
  162.                 }
  163.                 ph->storecolor[j] = 0;
  164.                 ph->storecolorbit[j] = 0;
  165.                 break;
  166.             case DST :
  167.                 if (GetToken(str, fp) == NULL || str[0] != '{') {
  168.                     return FALSE;
  169.                 }
  170.                 j = 0;
  171.                 while (GetToken(str, fp) != NULL && str[0] != EOFCODE && str[0] != '}') {
  172.                     i = GetIdentifier(str, datatoken);
  173.                     if (i == 0) {
  174.                         break;
  175.                     }
  176.                     ph->storedata[j] = i;
  177.                     if (GetToken(str, fp) == NULL || str[0] == EOFCODE || str[0] == '}') {
  178.                         break;
  179.                     }
  180.                     ph->storedatabit[j++] = atoi(str);
  181.                 }
  182.                 if (str[0] != '}') {
  183.                     return FALSE;
  184.                 }
  185.                 ph->storedata[j] = 0;
  186.                 ph->storedatabit[j] = 0;
  187.                 break;
  188.             }
  189.         } else {
  190.             return FALSE;
  191.         }
  192.     }
  193.     return FALSE;
  194. }
  195.  
  196. int        PicReadHeader_16_16(PicData *pd, FILE *fp, unsigned char *magic)
  197. {
  198.     PicHeader ph;
  199.     extern PicFunction PicFunction_16_16, PicFunction_25_7;
  200.  
  201.     if (memcmp(magic, "image", 5) != 0) {
  202.         return FALSE;
  203.     }
  204.     if (PicReadHeader_DPIC(&ph, fp) == FALSE) {
  205.         return FALSE;
  206.     }
  207.     pd->pixelX = ph.pixelX;
  208.     pd->pixelY = ph.pixelY;
  209.     pd->mode = ph.mode;
  210.     if (ph.mode != RLN) {
  211.         return FALSE;
  212.     }
  213.     pd->datasize = getlong(fp);
  214.     if (ph.storedata[0] == COL && ph.storedata[1] == LEN) {
  215.         if (ph.storedatabit[0] == 16 && ph.storedatabit[1] == 16) {
  216.             pd->fullcolor = FALSE;
  217.             pd->func = &PicFunction_16_16;
  218.             return TRUE;
  219.         } else if (ph.storedatabit[0] == 25 && ph.storedatabit[1] == 7) {
  220.             pd->func = &PicFunction_25_7;
  221.             return TRUE;
  222.         }
  223.     }
  224.     return FALSE;
  225. }
  226.  
  227. int        PicOpen_16_16(PicData *pd, FILE *fp, int flag)
  228. {
  229.     PicWork *work;
  230.     if (pd->flag == PIC_WRITE && flag == COMPRESS_TRUECOLOR) {
  231.         pd->func = &PicFunction_25_7;
  232.         return pd->func->PicOpen(pd, fp, 0);
  233.     }
  234.     if ((work = malloc(sizeof(PicWork))) == NULL) {
  235.         return FALSE;
  236.     }
  237.     pd->work = work;
  238.     work->fp = fp;
  239.     if (pd->flag == PIC_READ) {
  240.         fread(work->buffer, 1, BUFFERSIZE*sizeof(unsigned short), work->fp);
  241.         if (ferror(work->fp)) return FALSE;
  242.         work->nowpoint = 0;
  243.         work->nowcolor = r_short(work->buffer+work->nowpoint);work->nowpoint++;
  244.         work->nowlength = r_short(work->buffer+work->nowpoint);work->nowpoint++;
  245.     } else {
  246.         PicHeader ph;
  247.         ph.pixelX = pd->pixelX;
  248.         ph.pixelY = pd->pixelY;
  249.         ph.screenX = 4;
  250.         ph.screenY = 3;
  251.         ph.positionX = 0;
  252.         ph.positionY = 0;
  253.         ph.frame = 1;
  254.  
  255.         ph.storecolor[0] = GRN;    ph.storecolorbit[0] = 5;
  256.         ph.storecolor[1] = RED;    ph.storecolorbit[1] = 5;
  257.         ph.storecolor[2] = BLU;    ph.storecolorbit[2] = 5;
  258.         ph.storecolor[3] = TRP;    ph.storecolorbit[3] = 1;
  259.         ph.storecolor[4] = 0;    ph.storecolorbit[4] = 0;
  260.         ph.mode = RLN;
  261.         ph.storedata[0] = COL;    ph.storedatabit[0] = 16;
  262.         ph.storedata[1] = LEN;    ph.storedatabit[1] = 16;
  263.         ph.storedata[2] = 0;        ph.storedatabit[2] = 0;
  264.  
  265.         if (WritePicHeader_DPIC(&ph, fp) == FALSE) return FALSE;
  266.  
  267.         work->reduce = NULL;
  268.         work->pixelbuffer = NULL;
  269.         if ((work->reduce = PicColorReduceOpen(pd->pixelX, flag)) == NULL) {
  270.             return FALSE;
  271.         }
  272.         if ((work->pixelbuffer = malloc(sizeof(Pixel) * pd->pixelX)) == NULL) {
  273.             return FALSE;
  274.         }
  275.         work->seek = ftell(work->fp);
  276.         work->nowpoint = 0;
  277.         w_short(work->buffer+work->nowpoint, 0);work->nowpoint++;
  278.         w_short(work->buffer+work->nowpoint, 0);work->nowpoint++;
  279.         work->nowcolor = 0;
  280.         work->nowlength = 0;
  281.         work->totallength = 0;
  282.     }
  283.     return TRUE;
  284. }
  285.  
  286. static inline Pixel Convert_16_24(unsigned short color)
  287. {
  288. /*                        gggg grrr rrbb bbbt*/
  289. /*  gggg gggg rrrr rrrr bbbb bbbb tttt tttt*/
  290. /*
  291.     return ((color & 0xf800) << 16)
  292.          | ((color & 0x07c0) << 13)
  293.          | ((color & 0x003e) << 10)
  294.          | ((color & 0x0001) ? 0xff : 0);
  295. */
  296.     Pixel c = ((unsigned long)(color & 0xf800) << 11L)
  297.             | ((unsigned long)(color & 0x07c0) <<  8L)
  298.             | ((unsigned long)(color & 0x003e) <<  5L);
  299.     return  (c << 5L) | (c & 0x07070700L) | ((color & 0x0001) ? 0xff : 0);
  300. }
  301.  
  302. static inline unsigned short Convert_24_16(Pixel p)
  303. {
  304. /*
  305.     return ((p & 0xf8000000) >> 16)
  306.          | ((p & 0x00f80000) >> 13)
  307.          | ((p & 0x0000f800) >> 10)
  308.          | ((p & 0x00000080) ? 1 : 0);
  309. */
  310.     return ((p & 0xf8000000L) >> 16)
  311.          | ((p & 0x00f80000L) >> 13)
  312.          | ((p & 0x0000f800L) >> 10)
  313.          | ((p & 0x000000ffL) > 250 ? 1 : 0);
  314. }
  315.  
  316. int        PicOutput_16_16(PicData *pd, Pixel *p)
  317. {
  318.     int pixels = pd->pixelX;
  319.     PicWork *work = pd->work;
  320.     unsigned short nowlength = work->nowlength;
  321.     unsigned short nowcolor = work->nowcolor;
  322.     unsigned short color;
  323.     Pixel *pixel = work->pixelbuffer;
  324.     PicColorReduce(work->reduce, pixel, p);
  325.     for (; pixels > 0; --pixels) {
  326.         color = Convert_24_16(*pixel++);
  327.         if (color == nowcolor) {
  328.             if (nowlength == 65535) {
  329.                 w_short(work->buffer+work->nowpoint, nowcolor);work->nowpoint++;
  330.                 w_short(work->buffer+work->nowpoint, nowlength);work->nowpoint++;
  331.                 if (work->nowpoint == BUFFERSIZE) {
  332.                     fwrite(work->buffer, 1, BUFFERSIZE * sizeof(unsigned short), work->fp);
  333.                     if (ferror(work->fp)) return FALSE;
  334.                     work->totallength += BUFFERSIZE * 2;
  335.                     work->nowpoint = 0;
  336.                 }
  337.                 nowlength = 0;
  338.             }
  339.             nowlength++;
  340.         } else {
  341.             if (nowlength > 0) {
  342.                 w_short(work->buffer+work->nowpoint, nowcolor);work->nowpoint++;
  343.                 w_short(work->buffer+work->nowpoint, nowlength);work->nowpoint++;
  344.                 if (work->nowpoint == BUFFERSIZE) {
  345.                     fwrite(work->buffer, 1, BUFFERSIZE * sizeof(unsigned short), work->fp);
  346.                     if (ferror(work->fp)) return FALSE;
  347.                     work->totallength += BUFFERSIZE * 2;
  348.                     work->nowpoint = 0;
  349.                 }
  350.             }
  351.             nowlength = 1;
  352.             nowcolor = color;
  353.         }
  354.     }
  355.     work->nowcolor = nowcolor;
  356.     work->nowlength = nowlength;
  357.     return TRUE;
  358. }
  359.  
  360. int        PicInput_16_16(PicData *pd, Pixel *pixel)
  361. {
  362.     int pixels = pd->pixelX;
  363.     PicWork *work = pd->work;
  364.     Pixel nowpixel;
  365.     unsigned short nowlength = work->nowlength;
  366.     unsigned short nowcolor = work->nowcolor;
  367.     nowpixel = Convert_16_24(nowcolor);
  368.     while (nowlength <= pixels) {
  369.         pixels -= nowlength;
  370.         for (; nowlength > 0; --nowlength) {
  371.             *pixel++ = nowpixel;
  372.         }
  373.         nowcolor = r_short(work->buffer+work->nowpoint);work->nowpoint++;
  374.         nowlength = r_short(work->buffer+work->nowpoint);work->nowpoint++;
  375.         nowpixel = Convert_16_24(nowcolor);
  376.         if (work->nowpoint == BUFFERSIZE) {
  377.             fread(work->buffer, 1, BUFFERSIZE*sizeof(unsigned short), work->fp);
  378.             if (ferror(work->fp)) return FALSE;
  379.             work->nowpoint = 0;
  380.         }
  381.     }
  382.     nowlength -= pixels;
  383.     for (;pixels > 0; --pixels) {
  384.         *pixel++ = nowpixel;
  385.     }
  386.     work->nowlength = nowlength;
  387.     work->nowcolor = nowcolor;
  388.     return TRUE;
  389. }
  390.  
  391. int        PicClose_16_16(PicData *pd)
  392. {
  393.     PicWork *work = pd->work;
  394.     if (pd->flag == PIC_WRITE) {
  395.         if (work->nowlength > 0) {
  396.             w_short(work->buffer+work->nowpoint, work->nowcolor);work->nowpoint++;
  397.             w_short(work->buffer+work->nowpoint, work->nowlength);work->nowpoint++;
  398.         }
  399.         if (work->nowpoint > 0) {
  400.             fwrite(work->buffer, 1, work->nowpoint * sizeof(unsigned short), work->fp);
  401.             if (ferror(work->fp)) return FALSE;
  402.             work->totallength += work->nowpoint * 2;
  403.         }
  404.         work->totallength -= 4;
  405.         fseek(work->fp, work->seek, SEEK_SET);
  406.         if (ferror(work->fp)) return FALSE;
  407.         fputc( work->totallength >> 24        , work->fp);
  408.         fputc((work->totallength >> 16) & 0xff, work->fp);
  409.         fputc((work->totallength >>  8) & 0xff, work->fp);
  410.         fputc((work->totallength      ) & 0xff, work->fp);
  411.         PicColorReduceClose(work->reduce);
  412.         free(work->pixelbuffer);
  413.     }
  414.     fclose(work->fp);
  415.     free(work);
  416.     return TRUE;
  417. }
  418.  
  419. PicFunction PicFunction_16_16 = {
  420.     "PIC",
  421.     PicReadHeader_16_16,
  422.     PicOpen_16_16,
  423.     PicOutput_16_16,
  424.     PicInput_16_16,
  425.     PicClose_16_16
  426. };
  427.