home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / graf / fract3.zip / F16.C < prev    next >
C/C++ Source or Header  |  1989-08-07  |  5KB  |  184 lines

  1. /**************************************
  2. **
  3. ** F16.C : Code to read and write 16-bit fractal data sets.  Uses
  4. ** strictly Targa16 type 10 files (run-length encoded 16-bit RGB).
  5. */
  6.  
  7. /* Lee Daniel Crocker      CompuServe: 73407,2030   <== Preferred
  8. ** 1380 Jewett Ave.               BIX: lcrocker
  9. ** Pittsburg, CA  94565        Usenet: ...!ames!pacbell!sactoh0!siva!lee
  10. **
  11. ** This code is hereby placed in the public domain.  You are free to
  12. ** use, modify, usurp, laugh at, destroy, or otherwise abuse it in any
  13. ** way you see fit.
  14. **
  15. ** "If you steal from one author it's plagiarism; if you steal from
  16. ** many it's research."  --Wilson Mizner
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include "port.h"
  23. #include "targa_lc.h"
  24.  
  25. extern char rlebuf[258];    /* RLE-state variables */
  26. static int state, count, bufp;
  27.  
  28. /**************************************
  29. **
  30. ** Create Targa16 type 10 file at give hsize and vsize.  Optional
  31. ** comment block may be included by setting csize to a non-zero value
  32. ** and cp to point to a comment block of that many bytes.
  33. */
  34.  
  35. FILE *t16_create(char *fname, int hs, int vs, int csize, U8 *cp)
  36. {
  37.     char filename[64];
  38.     U8 header[HEADERSIZE];
  39.     FILE *fp;
  40.  
  41.     memset(header, 0, HEADERSIZE);
  42.     header[O_COMMENTLEN] = csize;
  43.     header[O_FILETYPE] = T_RLERGB;
  44.     STORE16(header[O_HSIZE], hs);
  45.     STORE16(header[O_VSIZE], vs);
  46.     header[O_ESIZE] = 16;
  47.     header[O_FLAGS] = M_ORIGIN | 1;
  48.  
  49.     strcpy(filename, fname);
  50.     if (strchr(filename, '.') == NULL) strcat(filename, ".TGA");
  51.     if ((fp = fopen(filename, WRITEMODE)) == NULL) return NULL;
  52.     fwrite(header, HEADERSIZE, 1, fp);
  53.     if (csize) fwrite(cp, csize, 1, fp);
  54.  
  55.     state = count = bufp = 0;
  56.     return fp;
  57. }
  58.  
  59. /**************************************
  60. **
  61. ** Open previously saved Targa16 type 10 file filling in hs, vs, and
  62. ** csize with values in the header.  If *csize is not zero, the block
  63. ** pointed to by cp is filled with the comment block.  The caller
  64. ** _must_ allocate 256 bytes for this purpose before calling.
  65. */
  66.  
  67. FILE *t16_open(char *fname, int *hs, int *vs, int *csize, U8 *cp)
  68. {
  69.     char filename[64];
  70.     U8 header[HEADERSIZE];
  71.     FILE *fp;
  72.  
  73.     strcpy(filename, fname);
  74.     if (strchr(filename, '.') == NULL) strcat(filename, ".TGA");
  75.     if ((fp = fopen(filename, READMODE)) == NULL) return NULL;
  76.  
  77.     fread(header, HEADERSIZE, 1, fp);
  78.     if ((header[O_FILETYPE] != T_RLERGB) || (header[O_ESIZE] != 16)) {
  79.         fclose(fp);
  80.         return NULL;
  81.     }
  82.     GET16(header[O_HSIZE], *hs);
  83.     GET16(header[O_VSIZE], *vs);
  84.     if (*csize = header[O_COMMENTLEN]) fread(cp, *csize, 1, fp);
  85.  
  86.     state = count = bufp = 0;
  87.     return fp;
  88. }
  89.  
  90. int t16_putline(FILE *fp, int hs, U16 *data)
  91. {
  92.     int i, v, lastv;
  93.  
  94.     for (i=0; i<hs; ++i) {
  95.         v = data[i];
  96.  
  97.         if (count == 128) {
  98.             if (state == 2) {
  99.                 putc(0xFF, fp);
  100.                 fwrite(rlebuf, 1, 2, fp);
  101.             } else if (state == 3) {
  102.                 putc(0x7F, fp);
  103.                 fwrite(rlebuf, 128, 2, fp);
  104.             }
  105.             state = bufp = count = 0;
  106.         }
  107.  
  108.         if (state == 0) {
  109.             STORE16(rlebuf[0], v);
  110.             bufp = 2;
  111.             count = state = 1;
  112.         } else if (state == 1) {
  113.             if (v == lastv) {
  114.                 state = 2;
  115.             } else {
  116.                 state = 3;
  117.                 STORE16(rlebuf[bufp], v);
  118.                 bufp += 2;
  119.             }
  120.             ++count;
  121.         } else if (state == 2) {
  122.             if (v == lastv) ++count;
  123.             else {
  124.                 putc((0x80|(count-1)), fp);
  125.                 fwrite(rlebuf, 1, 2, fp);
  126.                 STORE16(rlebuf[0], v);
  127.                 bufp = 2;
  128.                 count = state = 1;
  129.             }
  130.         } else if (state == 3) {
  131.             if (v == lastv) {
  132.                 putc((count-2), fp);
  133.                 fwrite(rlebuf, count-1, 2, fp);
  134.                 STORE16(rlebuf[0], v);
  135.                 bufp = count = state = 2;
  136.             } else {
  137.                 STORE16(rlebuf[bufp], v);
  138.                 bufp += 2;
  139.                 ++count;
  140.             }
  141.         }
  142.         lastv = v;
  143.     }
  144. }
  145.  
  146. int t16_getline(FILE *fp, int hs, U16 *data)
  147. {
  148.     int i;
  149.  
  150.     for (i=0; i<hs; ++i) {
  151.         if (state == 0) {
  152.             bufp = 0;
  153.             if ((count = getc(fp)) > 127) {
  154.                 state = 1;
  155.                 count -= 127;
  156.                 fread(rlebuf, 2, 1, fp);
  157.             } else {
  158.                 state = 2;
  159.                 ++count;
  160.                 fread(rlebuf, 2, count, fp);
  161.             }
  162.         }
  163.         GET16(rlebuf[bufp], data[i]);
  164.         if (--count == 0) state = 0;
  165.         if (state == 2) bufp += 2;
  166.     }
  167. }
  168.  
  169. int t16_flush(FILE *fp)
  170. {
  171.     if (state == 0) return;
  172.     else if (state == 1) {
  173.         putc(0, fp);
  174.         fwrite(rlebuf, 2, 1, fp);
  175.     } else if (state == 2) {
  176.         putc((0x80|(count-1)), fp);
  177.         fwrite(rlebuf, 2*count, 1, fp);
  178.     } else {
  179.         putc((count-1), fp);
  180.         fwrite(rlebuf, 2*count, 1, fp);
  181.     }
  182. }
  183.  
  184.