home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / c / tiff_lib / source / tif_pici.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  34.2 KB  |  923 lines

  1. #pragma warn -use
  2. static char     *sccsid = "@(#)TIFF/tif_picio.c 1.21, Copyright (c) Sam Leffler, Dieter Linde, "__DATE__;
  3. #pragma warn .use
  4. /*
  5.  * Copyright (c) 1988, 1990 by Sam Leffler, Oct 8 1990
  6.  * All rights reserved.
  7.  *
  8.  * This file is provided for unrestricted use provided that this legend is included on all tape media and as a part of the
  9.  * software program in whole or part.  Users may copy, modify or distribute this file at will.
  10.  *
  11.  * TIFF Library.
  12.  *
  13.  * Pixar Picio RLE Algorithm Support
  14.  *
  15.  * NB: This algorithm is not (currently) very effective because the state is reset at each scanline.  This
  16.  *   was done to avoid having dangling pointers into the raw data buffer that are invalidated by the flushing
  17.  *   that occurs in TIFFWriteScanline().  To fix this problem we need to add an encodestrip routine (to reset
  18.  *   state) and maintain state during decoding so that runs and such can be restarted when they cross scanline
  19.  *   boundaries.  However, since LZW already works on a strip basis and seems to be more effective, there's
  20.  *   not much reason to go to the trouble.
  21.  */
  22. #include <stdlib.h>
  23. #include "tiffio.h"
  24.  
  25. /*
  26.  * Each image is composed of a sequence of dumps, runs, partial dumps, and partial runs.  The first two
  27.  * bytes of a sequence contain a flag indicator and a count.  Flags are encoded in the upper 4 bits
  28.  * of the first byte while the lower 12 bits contain the count.
  29.  */
  30.  
  31. /*
  32.  * Tile flag indicators.
  33.  */
  34. #define PT_FILL            0                  /* fill input buffer */
  35. #define PT_FULLDUMP     1               /* full dump, use count */
  36. #define PT_FULLRUN      2               /* full run, length precedes pixel */
  37. #define PT_PARTDUMP     3               /* part dump, alpha constant */
  38. #define PT_PARTRUN      4               /* part run, alpha constant */
  39.  
  40. #define MAXPACKETSIZE      8        /* picio encoding state */
  41.  
  42. /* 
  43.  * Macros for unrolling loops.
  44.  */
  45. #define REPEAT4(n, op)    switch (n) { \
  46.                 case 4: \
  47.                     op; \
  48.                 case 3: \
  49.                     op; \
  50.                 case 2: \
  51.                     op; \
  52.                 case 1: \
  53.                     op; \
  54.             }
  55. #define    REPEAT8(n, op)    switch (n) { \
  56.                 case 8: \
  57.                     op; \
  58.                 case 7: \
  59.                     op; \
  60.                 case 6: \
  61.                     op; \
  62.                 case 5: \
  63.                     op; \
  64.                         case 4: \
  65.                             op; \
  66.                         case 3: \
  67.                             op; \
  68.                         case 2: \
  69.                             op; \
  70.                         case 1: \
  71.                             op; \
  72.                     }
  73. #define SPRAY4(nc, op)    switch (nc) { \
  74.                     case 4: \
  75.                         op[3]; \
  76.                     case 3: \
  77.                         op[2]; \
  78.                     case 2: \
  79.                         op[1]; \
  80.                     case 1: \
  81.                         op[0]; \
  82.                 }
  83.  
  84. struct  piciostate {
  85.         u_char     *startptr;
  86.         u_char     *lptr;                  /* pointer to length byte in run */
  87.         u_short len;                    /* length of run when in 16-bit mode */
  88.         short   count;                  /* repeat count of data in packet */
  89.         short   amark;                  /* index to alpha channel */
  90.         int     type;                   /* 4-bit packet type */
  91.         int     fulldisklength;         /* size of data + alpha unit */
  92.         int     infodisklength;         /* size of data unit */
  93.         u_char  *fulleobuffer;          /* output buffer fencepost for full packet */
  94.         u_char  *infoeobuffer;          /* output buffer fencepost for info packet */
  95. /*** temp buffers of data going to disk ***/
  96.         u_char  disk0buffer[MAXPACKETSIZE];
  97.         u_char  disk1buffer[MAXPACKETSIZE];
  98. /*** temp buffers of data in memory ***/
  99.         u_short core0buffer[MAXPACKETSIZE / 2];
  100.         u_short core1buffer[MAXPACKETSIZE / 2];
  101. };
  102.  
  103. static u_char     *newdisk, *olddisk;
  104. static u_short    *newcore, *oldcore;
  105.  
  106. #pragma warn -par
  107. /****************************************************************************
  108.  *
  109.  */
  110. static int
  111. pic8DecodeScanline(
  112.         TIFF        *tif,
  113.         register u_char    *op,
  114.         int         cc
  115.         )
  116. {
  117.         register u_char    *bp, *sp, *ep;
  118.         register int     npixels;
  119.         u_char         spare[4];
  120.         short         nc, flag, word, count, length;
  121.         static char    module[] = "PicioDecode";
  122.  
  123.         bp = tif->tif_rawcp;
  124.         ep = bp + tif->tif_rawcc;
  125.         npixels = tif->tif_dir.td_imagewidth;
  126.         nc = (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG ? tif->tif_dir.td_samplesperpixel : 1);
  127.         while (bp < ep && npixels > 0) {
  128.                 word = (bp[1] << 8) | bp[0];
  129.                 bp += 2;
  130.                 count = (word & 0xfff) + 1;
  131.                 switch (flag = (word >> 12)) {
  132.                     case PT_FULLRUN:
  133.                             while (count-- > 0) {
  134.  
  135.     /*
  136.          * The first byte holds a count.  The next bytes hold data to be repeated.
  137.          */
  138.                                     length = (*bp++) + 1;
  139.                                     sp = spare + nc;
  140.                                     REPEAT4(nc, *--sp = *bp++);
  141.                                     npixels -= length;
  142.                                     for (sp = spare; length-- > 0;)
  143.                                             SPRAY4(nc, *op++ = sp);
  144.                             }
  145.                             break;
  146.                     case PT_FULLDUMP:
  147.                             npixels -= count;
  148.                             for (count *= nc; count-- > 0; *op++ = *bp++)
  149.                                     ;
  150.                             break;
  151.                     case PT_PARTRUN:
  152.                             spare[0] = *bp++;
  153.                             while (count-- > 0) {
  154.  
  155.     /*
  156.          * The first byte is a count.  The next bytes are data to be repeated.
  157.          */
  158.                                     length = (*bp++) + 1;
  159.                                     sp = spare + nc;
  160.                                     REPEAT4(nc - 1, *--sp = *bp++);
  161.                                     npixels -= length;
  162.                                     for (sp = spare; length-- > 0;)
  163.                                             SPRAY4(nc, *op++ = sp);
  164.                             }
  165.                             break;
  166.                     case PT_PARTDUMP:
  167.  
  168.     /*
  169.          * The fixed value (normally alpha) is stored in the first byte.
  170.          */
  171.                             (sp = spare)[0] = *bp++;
  172.                             npixels -= count;
  173.                             while (count-- > 0) {
  174.                                     REPEAT4(nc - 1, *op++ = *bp++);
  175.                                     *op++ = sp[0];
  176.                             }
  177.                             break;
  178.                     default:
  179.                             TIFFError(module, "%s: Unknown flag 0x%x at scanline %d", tif->tif_name, flag, tif->tif_row);
  180.                             return(0);
  181.                 }
  182.         }
  183.         tif->tif_rawcc -= (bp - tif->tif_rawcp);
  184.         tif->tif_rawcp = bp;
  185.         if (npixels > 0) {
  186.                    TIFFError(module, "%s: Not enough data for scanline %d", tif->tif_name, tif->tif_row);
  187.                 return(0);
  188.         }
  189.         return(1);
  190. }
  191. #pragma warn .par
  192.  
  193. #pragma warn -par
  194. /****************************************************************************
  195.  *
  196.  */
  197. static int
  198. pic16DecodeScanline(
  199.         TIFF         *tif,
  200.         register u_char    *op,
  201.         int         cc
  202.         )
  203. {
  204.         register u_char     *bp, *ep;
  205.         register int         npixels;
  206.         register u_short     *sp;
  207.         short             nc, flag, word, count, length;
  208.         u_short         spare[4];
  209.         static char         module[] = "PicioDecode";
  210.  
  211.         bp = tif->tif_rawcp;
  212.         ep = bp + tif->tif_rawcc;
  213.         npixels = tif->tif_dir.td_imagewidth;
  214.         nc = (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG ? tif->tif_dir.td_samplesperpixel : 1);
  215.         while (bp < ep && npixels > 0) {
  216.                 word = (bp[1] << 8) | bp[0];
  217.                 bp += 2;
  218.                 count = (word & 0xfff) + 1;
  219.                 switch (flag = (word >> 12)) {
  220.                     case PT_FULLRUN:
  221.                             while (count-- > 0) {
  222.  
  223.     /*
  224.          * The first byte holds a count.  The next bytes hold data to be repeated.
  225.          */
  226.                                     length = ((bp[1] << 8) | bp[0]) + 1; 
  227.                                     bp += 2;
  228.                                     sp = spare + nc;
  229.                                     REPEAT4(nc, *--sp = bp[0]|(bp[1] << 8); bp += 2);
  230.                                     npixels -= length;
  231.                                     for (sp = spare; length-- > 0;)
  232.                                             SPRAY4(nc, *((u_short *)op)++ = sp);
  233.                             }
  234.                             break;
  235.                     case PT_FULLDUMP:
  236.                             npixels -= count;
  237.                             while (count-- > 0)
  238.                                     REPEAT4(nc, *((u_short *)op)++ = bp[0]|(bp[1] << 8); bp += 2);
  239.                             break;
  240.                     case PT_PARTRUN:
  241.                             spare[0] = bp[0]|(bp[1] << 8); 
  242.                             bp += 2;
  243.                             while (count-- > 0) {
  244.  
  245.     /*
  246.          * The first byte is a count.  The next bytes are data to be repeated.
  247.          */
  248.                                     length = ((bp[1] << 8) | bp[0]) + 1; 
  249.                                     bp += 2;
  250.                                     sp = spare + nc;
  251.                                     REPEAT4(nc - 1, *--sp = bp[0]|(bp[1] << 8); bp +=2);
  252.                                     npixels -= length;
  253.                                     for (sp = spare; length-- > 0;)
  254.                                             SPRAY4(nc, *((u_short *)op)++ = sp);
  255.                             }
  256.                             break;
  257.                     case PT_PARTDUMP:
  258.  
  259.     /*
  260.          * The fixed value (normally alpha) is stored in the first byte.
  261.          */
  262.                             (sp = spare)[0] = bp[0]|(bp[1] << 8); 
  263.                             bp += 2;
  264.                             npixels -= count;
  265.                             while (count-- > 0) {
  266.                                     REPEAT4(nc - 1, *((u_short *)op)++ = bp[0]|(bp[1] << 8); bp +=2);
  267.                                     *((u_short *)op)++ = sp[0];
  268.                             }
  269.                             break;
  270.                     default:
  271.                             TIFFError(module, "%s: Unknown flag 0x%x at scanline %d", tif->tif_name, flag, tif->tif_row);
  272.                             return(0);
  273.                 }
  274.         }
  275.         tif->tif_rawcc -= (bp - tif->tif_rawcp);
  276.         tif->tif_rawcp = bp;
  277.         if (npixels > 0) {
  278.                    TIFFError(module, "%s: Not enough data for scanline %d", tif->tif_name, tif->tif_row);
  279.                 return(0);
  280.         }
  281.         return(1);
  282. }
  283. #pragma warn .par
  284.  
  285. /****************************************************************************
  286.  *
  287.  */
  288. static int
  289. PicioDecodeStrip(
  290.         TIFF     *tif
  291.         )
  292. {
  293.         switch (tif->tif_dir.td_bitspersample) {
  294.             case 8:
  295.                     tif->tif_decoderow = pic8DecodeScanline;
  296.                     break;
  297.             case 16:
  298.                     tif->tif_decoderow = pic16DecodeScanline;
  299.                     break;
  300.             default:
  301.                     TIFFError("PicioDecode", "Can't handle %d-bit pictures", tif->tif_dir.td_bitspersample);
  302.                     return(0);
  303.         }
  304.         return(1);
  305. }
  306.  
  307. /****************************************************************************
  308.  * Startpacket takes the old and new pixels and starts the requested packet using them.
  309.  */
  310. static u_char *
  311. startpacket(
  312.     TIFF    *tif,
  313.     u_char    *ptr, 
  314.     short    type
  315.     )
  316. {
  317.         register struct piciostate    *ps;
  318.         register u_char         *dp;
  319.  
  320.         /*
  321.          * Set up packet type and count.  The packet count is incremented as the data is repeated.  These
  322.          * two values are merged and written when ending the packet.
  323.          */
  324.         ps = (struct piciostate *)tif->tif_data;
  325.         if (ptr > ps->fulleobuffer) {
  326.                    tif->tif_rawcc += ptr - (u_char *)tif->tif_rawcp;
  327.                 if (!TIFFFlushData(tif))
  328.                            return(NULL);
  329.                 ptr = (u_char *)tif->tif_rawcp;
  330.         }
  331.         ps->type = type;
  332.         ps->count = 0;
  333.         ps->startptr = ptr;
  334.         ptr += 2;    /* skip packet header */
  335.         switch (type) {
  336.             case 0:
  337.                     ps->type = PT_FULLDUMP;
  338.                     dp = newdisk;
  339.                     REPEAT8(ps->fulldisklength, *ptr++ = *dp++);
  340.                     break;
  341.  
  342.             case PT_FULLDUMP:
  343.             case PT_FULLRUN:
  344.                     if (type == PT_FULLRUN) {
  345.                             ps->lptr = ptr;
  346.                             *ptr++ = 1;
  347.                             if (tif->tif_dir.td_bitspersample == 16) {
  348.                                     ps->len = 1;
  349.                                     *ptr++ = 0;
  350.                             }
  351.                     }
  352.                     dp = olddisk;
  353.                     REPEAT8(ps->fulldisklength, *ptr++ = *dp++);
  354.                     break;
  355.  
  356.             case PT_PARTRUN:
  357.             case PT_PARTDUMP:
  358.                     dp = olddisk + ps->infodisklength;
  359.                     REPEAT8(ps->fulldisklength - ps->infodisklength, *ptr++ = *dp++);
  360.                     if (type == PT_PARTRUN) {
  361.                             ps->lptr = ptr;
  362.                             *ptr++ = 1;
  363.                             if (tif->tif_dir.td_bitspersample == 16) {
  364.                                     ps->len = 1;
  365.                                     *ptr++ = 0;
  366.                             }
  367.                     }
  368.                     dp = olddisk;
  369.                     REPEAT8(ps->infodisklength, *ptr++ = *dp++);
  370.                     break;
  371.            }
  372.         return(ptr);
  373. }
  374.  
  375. /****************************************************************************
  376.  * Set the packet header from the accumulated state information.
  377.  */
  378. static void
  379. endpacket(
  380.           register struct piciostate    *ps
  381.           )
  382. {
  383.            ps->count |= ps->type << 12;
  384.         ps->startptr[1] = ps->count >> 8;
  385.         ps->startptr[0] = ps->count;
  386. }
  387.  
  388. /*
  389.  * Yech -- this knows about bp & runstatus.
  390.  */
  391. #define startnewbuffer(tif, pt)    { \
  392.                         endpacket((struct piciostate *)tif->tif_data); \
  393.                         tif->tif_rawcc += bp - (u_char *)tif->tif_rawcp; \
  394.                         if (!TIFFFlushData(tif)) \
  395.                                 return(-1); \
  396.                         bp = startpacket(tif, tif->tif_rawcp, runstatus = pt); \
  397.                         if (bp == NULL) \
  398.                                 return(-1); \
  399.                 }
  400.  
  401. /* 
  402.  * State indicators used in encoding.
  403.  */
  404. #define PT_UNKNOWN      -1
  405. #define PT_CFULLRUN     -2
  406. #define PT_STARTUP      -3
  407. #define PT_CPARTRUN     -4
  408.  
  409. /*
  410.  * To encode tile type + same-pixel + same-alpha into a single value, we use the following magic constants.
  411.  */
  412. #define SP_FALSE           (0 * (PT_PARTRUN - PT_CPARTRUN + 1))
  413. #define SP_TRUE         (1 * (PT_PARTRUN - PT_CPARTRUN + 1))
  414. #define SA_FALSE        (2 * SP_FALSE)
  415. #define SA_TRUE         (4 * SP_TRUE)
  416.  
  417. /****************************************************************************
  418.  * Setup encoding state.
  419.  */
  420. static int
  421. PicioStripEncode(
  422.           register TIFF    *tif
  423.           )
  424. {
  425.         register struct piciostate    *ps;
  426.         int                 bytespersample;
  427.  
  428.         if (tif->tif_data != NULL)
  429.                    return(1);
  430.         if (tif->tif_dir.td_bitspersample != 8 && tif->tif_dir.td_bitspersample != 16) {
  431.                    TIFFError("PicioEncode", "Can't handle %d-bit pictures", tif->tif_dir.td_bitspersample);
  432.                 return(0);
  433.         }
  434.         if ((tif->tif_data = malloc(sizeof(struct piciostate))) == NULL) {
  435.                    TIFFError("PicioEncode", "No space for picio state block");
  436.                 return(0);
  437.         }
  438.         bzero(tif->tif_data, sizeof(struct piciostate));
  439.         ps = (struct piciostate *)tif->tif_data;
  440.         if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) {
  441.                    ps->fulldisklength = tif->tif_dir.td_samplesperpixel;
  442.                 if ((ps->infodisklength = tif->tif_dir.td_samplesperpixel) > 3)
  443.                            ps->infodisklength = 3;
  444.                 ps->amark = tif->tif_dir.td_matteing ? tif->tif_dir.td_samplesperpixel - 1 : 3;
  445.         } 
  446.         else {
  447.                 ps->fulldisklength = ps->infodisklength = 1;
  448.                 ps->amark = 0;
  449.         }
  450.         bytespersample = tif->tif_dir.td_bitspersample <= 8 ? 1 : tif->tif_dir.td_bitspersample <= 16 ? 2 : 4;
  451.         ps->fulldisklength *= bytespersample;
  452.         ps->infodisklength *= bytespersample;
  453.  
  454.         /*
  455.          * fulleobuffer & infoeobuffer mark the last spot in the buffer at which a packet can be placed
  456.          * (either a fulldisklength or infodisklength packet).  The 2+ is for the 2 byte packet type and length.
  457.          */
  458.         ps->fulleobuffer = (u_char *)tif->tif_rawdata + tif->tif_rawdatasize - (2 + ps->fulldisklength) - 1;
  459.         ps->infoeobuffer = (u_char *)tif->tif_rawdata + tif->tif_rawdatasize - (2 + ps->infodisklength) - 1;
  460.         return(1);
  461. }
  462.  
  463. /****************************************************************************
  464.  * Encode a scanline of pixels.
  465.  */
  466. static int
  467. PicioEncode(
  468.            TIFF         *tif,
  469.         register u_char    *ip,
  470.         int        cc
  471.         )
  472. {
  473.         register u_char            *bp;
  474.         register struct piciostate     *ps;
  475.         u_char                 *dp, *ep;
  476.         int                 cmpstatus, runstatus, nc, hasalphachannel;
  477.         u_short             *cp1, *cp2, *wp;
  478.  
  479.         ps = (struct piciostate *)tif->tif_data;
  480.         ep = ip + cc;
  481.         bp = (u_char *)tif->tif_rawcp;
  482.         if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) {
  483.                 nc = tif->tif_dir.td_samplesperpixel;
  484.                 hasalphachannel = tif->tif_dir.td_matteing;
  485.         } 
  486.         else {
  487.                 nc = 1;
  488.                 hasalphachannel = 0;
  489.         }
  490.         oldcore = ps->core0buffer;
  491.         newcore = ps->core1buffer;
  492.         olddisk = ps->disk0buffer;
  493.         newdisk = ps->disk1buffer;
  494.  
  495.         /* 
  496.          * Setup initial alpha to be different.
  497.          */
  498.         oldcore[ps->amark] = 0;
  499.         newcore[ps->amark] = -1;
  500.  
  501.         /*
  502.          * Process each pixel with a finite state machine with one-pixel look-ahead.  The look-ahead is used to compress
  503.          * identical pixels into "pixel runs".  The states of encoding process include all the packet types, filled
  504.          * out with a startup state (used only at startup) and an unknown state (used when we have no packet open and
  505.          * do not know yet what kind of packet this last pixel will start.  Also needed are temporary runlength states
  506.          * which are needed, for example, when we have just finished one run in a runlength packet and do not know whether this
  507.          * last pixel is the start of a new run or the start of a whole new (dump) packet.
  508.          */
  509.         runstatus = PT_STARTUP;
  510.         while (ip < ep) {
  511.  
  512.          /*
  513.          * Swap pointers to new and old data buffers.
  514.          */
  515. #define    SWAP(t, a, b)    { \
  516.                 t    tmp; \
  517.                 tmp = a; \
  518.                 a = b; \
  519.                 b = tmp; \
  520.             }
  521.                   SWAP(u_short *, oldcore, newcore);
  522.                 SWAP(u_char *, olddisk, newdisk);
  523.  
  524.         /*
  525.          * Next move the new pixel from the user buffer into the local array and set up the cmpstatus flag to
  526.          * indicate if the new and old pixels agree fully, or just in the flat field (alpha) component.
  527.          */
  528.                 cmpstatus = SP_TRUE;
  529.                 cp1 = newcore; 
  530.                 cp2 = oldcore; 
  531.                 dp = newdisk;
  532.                 if (tif->tif_dir.td_bitspersample == 8) {
  533.                            REPEAT4(nc, *cp1 = *ip++;
  534.                                 if (*cp2++ != *cp1)
  535.                                     cmpstatus = SP_FALSE;
  536.                                 *dp++ = *cp1++);
  537.                 } 
  538.                 else {
  539.                            wp = (u_short *)ip;    /* XXX for non-pcc compilers */
  540.                         REPEAT4(nc, *cp1 = *wp++;
  541.                                 if (*cp2++ != *cp1)
  542.                                     cmpstatus = SP_FALSE;
  543.                                 *dp++ = *cp1;
  544.                                 *dp++ = *cp1++ >> 8);
  545.                         ip = (u_char *)wp;
  546.                 }
  547.                 cmpstatus += oldcore[ps->amark] == newcore[ps->amark] ? SA_TRUE : SA_FALSE;
  548.  
  549.        /*
  550.          * Here is the main loop that decides how to handle the new pixel based on the current state.
  551.          */
  552.                 switch (runstatus + cmpstatus) {
  553.  
  554.           /*
  555.          * Continue the full run because the new pixel matches the old.
  556.          */
  557.                     case PT_FULLRUN + SP_TRUE + SA_FALSE:
  558.                     case PT_FULLRUN + SP_TRUE + SA_TRUE:
  559.  
  560.          /*
  561.          * The run count just overflowed.  Go to the CFULLRUN state, because this run is done, and we do not
  562.          * know whether to start a new packet or just a new run.
  563.          */
  564.                             if (tif->tif_dir.td_bitspersample == 16) {
  565.                                     ps->lptr[0] = ++(ps->len);
  566.                                     ps->lptr[1] = ps->len >> 8;
  567.                                     if (ps->len != 0)
  568.                                             break;
  569.                                     ps->lptr[0] = --(ps->len);
  570.                                     ps->lptr[1] = ps->len >> 8;
  571.                             } 
  572.                             else {
  573.                                     if (++(*ps->lptr) != 0)
  574.                                             break;
  575.                                     (*ps->lptr)--;
  576.                             }
  577.                             /*** fall thru... ***/
  578.  
  579.                     case PT_FULLRUN + SP_FALSE + SA_FALSE:
  580.                     case PT_FULLRUN + SP_FALSE + SA_TRUE:
  581.  
  582.           /*
  583.          * Terminate the current run and go to CFULLRUN to decide whether to start a new run with this
  584.          * pixel or to start a whole new packet.
  585.          */
  586.                             runstatus = PT_CFULLRUN;
  587.                             break;
  588.  
  589.            /*
  590.          * In the middle of a fullrun packet; wait to see whether to start a new run, or whether to end this 
  591.          * packet and start a new packet.
  592.          */
  593.                     case PT_CFULLRUN + SP_TRUE + SA_FALSE:
  594.                     case PT_CFULLRUN + SP_TRUE + SA_TRUE:
  595.  
  596.            /*
  597.          * Start a new run.  Increment the packet count which holds the number of runs in this packet.  
  598.          * Put out the run length (1, meaning 1 repetition or 2 instances) and the full component information.
  599.          */
  600.                             if (bp > ps->fulleobuffer) {
  601.                                     startnewbuffer(tif, PT_FULLRUN);
  602.                             } 
  603.                             else {
  604.                                     ps->count++;
  605.                                     ps->lptr = bp;
  606.                                     *bp++ = 1;
  607.                                     if (tif->tif_dir.td_bitspersample == 16) {
  608.                                             ps->len = 1;
  609.                                             *bp++ = 0;
  610.                                     }
  611.                                     dp = newdisk;
  612.                                     REPEAT8(ps->fulldisklength, *bp++ = *dp++);
  613.                             }
  614.                             runstatus = PT_FULLRUN;
  615.                             break;
  616.  
  617.                     case PT_CFULLRUN + SP_FALSE + SA_TRUE:
  618.  
  619.          /*
  620.          * End this packet and start a partial dump packet, because at least the alpha stayed constant.
  621.          */
  622.                             endpacket(ps);
  623.                             bp = startpacket(tif, bp, runstatus = PT_PARTDUMP);
  624.                             if (bp == 0)
  625.                                     return(-1);
  626.                             break;
  627.  
  628.                     case PT_CFULLRUN + SP_FALSE + SA_FALSE:
  629.                             endpacket(ps);
  630.                             bp = startpacket(tif, bp, runstatus = PT_FULLDUMP);
  631.                             if (bp == 0)
  632.                                     return(-1);
  633.                             break;
  634.  
  635.                     case PT_FULLDUMP + SP_TRUE + SA_TRUE:
  636.                     case PT_FULLDUMP + SP_TRUE + SA_FALSE:
  637.  
  638.         /*
  639.          * End this full dump packet and start a full run because of the match.
  640.          */
  641.                             endpacket(ps);
  642.                             bp = startpacket(tif, bp, runstatus = PT_FULLRUN);
  643.                             if (bp == 0)
  644.                                     return(-1);
  645.                             break;
  646.  
  647.                     case PT_FULLDUMP + SP_FALSE + SA_TRUE:
  648.                             endpacket(ps);
  649.                             bp = startpacket(tif, bp, runstatus = PT_PARTDUMP);
  650.                             if (bp == 0)
  651.                                     return(-1);
  652.                             break;
  653.  
  654.                     case PT_FULLDUMP + SP_FALSE + SA_FALSE:
  655.  
  656.          /*
  657.          * Continue the dump packet.  Write the full component information into the buffer.
  658.          */
  659.                             if (bp > ps->fulleobuffer) {
  660.                                     startnewbuffer(tif, PT_FULLDUMP);
  661.                             } 
  662.                             else {
  663.                                     ps->count++;
  664.                                     dp = olddisk;
  665.                                     REPEAT8(ps->fulldisklength, *bp++ = *dp++);
  666.                             }
  667.                             break;
  668.  
  669.                     case PT_PARTRUN + SP_TRUE + SA_FALSE:
  670.                     case PT_PARTRUN + SP_TRUE + SA_TRUE:
  671.  
  672.         /*
  673.          * Continue the part run packet.
  674.          */
  675.                             if (tif->tif_dir.td_bitspersample == 16) {
  676.                                     ps->lptr[0] = ++(ps->len);
  677.                                     ps->lptr[1] = ps->len >> 8;
  678.                                     if (ps->len != 0)
  679.                                             break;
  680.                                     ps->lptr[0] = --(ps->len);
  681.                                     ps->lptr[1] = ps->len >> 8;
  682.                             } 
  683.                             else {
  684.                                     if (++(*ps->lptr) != 0)
  685.                                             break;
  686.                                     (*ps->lptr)--;
  687.                             }
  688.                             /*** fall thru... ***/
  689.  
  690.                     case PT_PARTRUN + SP_FALSE + SA_TRUE:
  691.  
  692.          /*
  693.          * Go to CPARTRUN because this may just be the start of a new run for this packet.
  694.          */
  695.                             runstatus = PT_CPARTRUN;
  696.                             break;
  697.  
  698.                     case PT_PARTRUN + SP_FALSE + SA_FALSE:
  699.  
  700.         /*
  701.          * With no match at all, we have to end this part run packet.  With only this last pixel to start with, we do not
  702.          * know what packet to start next.  Thus we go to the UNKNOWN state.
  703.          */
  704.                             endpacket(ps);
  705.                             runstatus = PT_UNKNOWN;
  706.                             break;
  707.  
  708.                     case PT_CPARTRUN + SP_TRUE + SA_FALSE:
  709.                     case PT_CPARTRUN + SP_TRUE + SA_TRUE:
  710.                             if (bp > ps->infoeobuffer) {
  711.                                     startnewbuffer(tif, PT_PARTRUN);
  712.                             } 
  713.                             else {
  714.                                     ps->count++;
  715.                                     ps->lptr = bp;
  716.                                     *bp++ = 1;
  717.                                     if (tif->tif_dir.td_bitspersample == 16) {
  718.                                             ps->len = 1;
  719.                                             *bp++ = 0;
  720.                                     }
  721.                                     dp = newdisk;
  722.                                     REPEAT8(ps->infodisklength, *bp++ = *dp++);
  723.                             }
  724.                             runstatus = PT_PARTRUN;
  725.                             break;
  726.  
  727.                     case PT_CPARTRUN + SP_FALSE + SA_TRUE:
  728.                             endpacket(ps);
  729.                             bp = startpacket(tif, bp, runstatus = PT_PARTDUMP);
  730.                             if (bp == 0)
  731.                                     return(-1);
  732.                             break;
  733.  
  734.                     case PT_CPARTRUN + SP_FALSE + SA_FALSE:
  735.                             endpacket(ps);
  736.                             bp = startpacket(tif, bp, runstatus = PT_FULLDUMP);
  737.                             if (bp == 0)
  738.                                     return(-1);
  739.                             break;
  740.  
  741.                     case PT_PARTDUMP + SP_TRUE + SA_FALSE:
  742.                     case PT_PARTDUMP + SP_TRUE + SA_TRUE:
  743.  
  744.          /*
  745.          * This dump packet ends and a partial run packet begins with these last two pixels.
  746.          */
  747.                             endpacket(ps);
  748.                             bp = startpacket(tif, bp, runstatus = PT_PARTRUN);
  749.                             if (bp == 0)
  750.                                     return(-1);
  751.                             break;
  752.  
  753.                     case PT_PARTDUMP + SP_FALSE + SA_TRUE:
  754.  
  755.          /*
  756.          * The partial dump packet continues.
  757.          */
  758.                             if (bp > ps->infoeobuffer) {
  759.                                     startnewbuffer(tif, PT_PARTDUMP);
  760.                             } 
  761.                             else {
  762.                                     ps->count++;
  763.                                     dp = olddisk;
  764.                                     REPEAT8(ps->infodisklength, *bp++ = *dp++);
  765.                             }
  766.                             break;
  767.  
  768.                     case PT_PARTDUMP + SP_FALSE + SA_FALSE:
  769.  
  770.         /*
  771.          * The partial dump ends because alpha is no longer constant.  Finish off this packet and go to the unknown
  772.          * state with this new pixel.
  773.          */
  774.                             if (bp > ps->infoeobuffer) {
  775.                                     startnewbuffer(tif, PT_PARTDUMP);
  776.                             } 
  777.                             else {
  778.                                     ps->count++;
  779.                                     dp = olddisk;
  780.                                     REPEAT8(ps->infodisklength, *bp++ = *dp++);
  781.                             }
  782.                             endpacket(ps);
  783.                             runstatus = PT_UNKNOWN;
  784.                             break;
  785.  
  786.                     case PT_STARTUP + SP_FALSE + SA_FALSE:
  787.                     case PT_STARTUP + SP_FALSE + SA_TRUE:
  788.                     case PT_STARTUP + SP_TRUE + SA_FALSE:
  789.                     case PT_STARTUP + SP_TRUE + SA_TRUE:
  790.  
  791.            /*
  792.          * The only thing to do when starting is to start a packet.  However, we do not know which to start until 
  793.          * we have two pixels, so we go to the unknown state.
  794.          */
  795.                             runstatus = PT_UNKNOWN;
  796.                             break;
  797.  
  798.                     case PT_UNKNOWN + SP_TRUE + SA_FALSE:
  799.                     case PT_UNKNOWN + SP_TRUE + SA_TRUE:
  800.                             runstatus = hasalphachannel ? PT_PARTRUN : PT_FULLRUN;
  801.                             bp = startpacket(tif, bp, runstatus);
  802.                             if (bp == 0)
  803.                                     return(-1);
  804.                             break;
  805.  
  806.                     case PT_UNKNOWN + SP_FALSE + SA_TRUE:
  807.                             bp = startpacket(tif, bp, runstatus = PT_PARTDUMP);
  808.                             if (bp == 0)
  809.                                     return(-1);
  810.                             break;
  811.  
  812.                     case PT_UNKNOWN + SP_FALSE + SA_FALSE:
  813.                             bp = startpacket(tif, bp, runstatus = PT_FULLDUMP);
  814.                             if (bp == 0)
  815.                                     return(-1);
  816.                             break;
  817.                    }
  818.            }
  819.  
  820.         /*
  821.          * The following code handles the cleanup at the end of the scanline -- we must flush the current packet.
  822.          */
  823.         switch (runstatus) {
  824.             case PT_FULLRUN:    /* everything is up to date */
  825.                     break;
  826.  
  827.             case PT_CFULLRUN:    /* add the last new pixel as a run with repeat count 0 */
  828.                     if (bp > ps->fulleobuffer) {
  829.                             startnewbuffer(tif, 0);
  830.                     } 
  831.                     else {
  832.                             ps->count++;
  833.                             *bp++ = 0;
  834.                             if (tif->tif_dir.td_bitspersample == 16)
  835.                                     *bp++ = 0;
  836.                             dp = newdisk;
  837.                             REPEAT8(ps->fulldisklength, *bp++ = *dp++);
  838.                     }
  839.                     break;
  840.  
  841.             case PT_FULLDUMP:    /* add this new pixel as the last pixel in a dump */
  842.                     if (bp > ps->fulleobuffer) {
  843.                             startnewbuffer(tif, 0);
  844.                     } 
  845.                     else {
  846.                             ps->count++;
  847.                             dp = newdisk;
  848.                             REPEAT8(ps->fulldisklength, *bp++ = *dp++);
  849.                     }
  850.                     break;
  851.  
  852.             case PT_PARTRUN:    /* we are up to date */
  853.                     break;
  854.  
  855.             case PT_CPARTRUN:    /* see CFULLRUN above */
  856.                     if (bp > ps->infoeobuffer) {
  857.                             startnewbuffer(tif, 0);
  858.                     } 
  859.                     else {
  860.                             ps->count++;
  861.                             *bp++ = 0;
  862.                             if (tif->tif_dir.td_bitspersample == 16)
  863.                                     *bp++ = 0;
  864.                             dp = newdisk;
  865.                             REPEAT8(ps->infodisklength, *bp++ = *dp++);
  866.                     }
  867.                     break;
  868.  
  869.             case PT_PARTDUMP:    /* see FULLDUMP above */
  870.                     if (bp > ps->infoeobuffer) {
  871.                             startnewbuffer(tif, 0);
  872.                     } 
  873.                     else {
  874.                             ps->count++;
  875.                             dp = newdisk;
  876.                             REPEAT8(ps->infodisklength, *bp++ = *dp++);
  877.                     }
  878.                     break;
  879.  
  880.             case PT_STARTUP:
  881.                     break;
  882.  
  883.             case PT_UNKNOWN:    /* we are caught with one pixel in the hand and no packet to add it to; we start a simple fulldump packet */
  884.                     bp = startpacket(tif, bp, 0);
  885.                     if (bp == 0)
  886.                             return(-1);
  887.                     break;
  888.            }
  889.         endpacket(ps);
  890.         tif->tif_rawcc += bp - (u_char *)tif->tif_rawcp;
  891.         tif->tif_rawcp = (u_char *)bp;
  892.         return(1);
  893. }
  894.  
  895. /****************************************************************************
  896.  *
  897.  */
  898. static void
  899. PicioCleanup(
  900.            TIFF     *tif
  901.            )
  902. {
  903.         if (tif->tif_data != NULL) {
  904.                    free(tif->tif_data);
  905.                    tif->tif_data = NULL;
  906.         }
  907. }
  908.  
  909. /****************************************************************************
  910.  *
  911.  */
  912. int
  913. TIFFInitPicio(
  914.         TIFF    *tif
  915.         )
  916. {
  917.         tif->tif_stripdecode = PicioDecodeStrip;
  918.         tif->tif_stripencode = PicioStripEncode;
  919.         tif->tif_encoderow = PicioEncode;
  920.         tif->tif_cleanup = PicioCleanup;
  921.         return(1);
  922. }
  923.