ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_packbits.c
Go to the documentation of this file.
00001 /* $Id: tif_packbits.c,v 1.13.2.2 2010-06-08 18:50:42 bfriesen Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1988-1997 Sam Leffler
00005  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 #include "tiffiop.h"
00028 #ifdef PACKBITS_SUPPORT
00029 /*
00030  * TIFF Library.
00031  *
00032  * PackBits Compression Algorithm Support
00033  */
00034 #include <stdio.h>
00035 
00036 static int
00037 PackBitsPreEncode(TIFF* tif, tsample_t s)
00038 {
00039     (void) s;
00040 
00041         if (!(tif->tif_data = (tidata_t)_TIFFmalloc(sizeof(tsize_t))))
00042         return (0);
00043     /*
00044      * Calculate the scanline/tile-width size in bytes.
00045      */
00046     if (isTiled(tif))
00047         *(tsize_t*)tif->tif_data = TIFFTileRowSize(tif);
00048     else
00049         *(tsize_t*)tif->tif_data = TIFFScanlineSize(tif);
00050     return (1);
00051 }
00052 
00053 static int
00054 PackBitsPostEncode(TIFF* tif)
00055 {
00056         if (tif->tif_data)
00057             _TIFFfree(tif->tif_data);
00058     return (1);
00059 }
00060 
00061 /*
00062  * NB: tidata is the type representing *(tidata_t);
00063  *     if tidata_t is made signed then this type must
00064  *     be adjusted accordingly.
00065  */
00066 typedef unsigned char tidata;
00067 
00068 /*
00069  * Encode a run of pixels.
00070  */
00071 static int
00072 PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
00073 {
00074     unsigned char* bp = (unsigned char*) buf;
00075     tidata_t op, ep, lastliteral;
00076     long n, slop;
00077     int b;
00078     enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
00079 
00080     (void) s;
00081     op = tif->tif_rawcp;
00082     ep = tif->tif_rawdata + tif->tif_rawdatasize;
00083     state = BASE;
00084     lastliteral = 0;
00085     while (cc > 0) {
00086         /*
00087          * Find the longest string of identical bytes.
00088          */
00089         b = *bp++, cc--, n = 1;
00090         for (; cc > 0 && b == *bp; cc--, bp++)
00091             n++;
00092     again:
00093         if (op + 2 >= ep) {     /* insure space for new data */
00094             /*
00095              * Be careful about writing the last
00096              * literal.  Must write up to that point
00097              * and then copy the remainder to the
00098              * front of the buffer.
00099              */
00100             if (state == LITERAL || state == LITERAL_RUN) {
00101                 slop = op - lastliteral;
00102                 tif->tif_rawcc += lastliteral - tif->tif_rawcp;
00103                 if (!TIFFFlushData1(tif))
00104                     return (-1);
00105                 op = tif->tif_rawcp;
00106                 while (slop-- > 0)
00107                     *op++ = *lastliteral++;
00108                 lastliteral = tif->tif_rawcp;
00109             } else {
00110                 tif->tif_rawcc += op - tif->tif_rawcp;
00111                 if (!TIFFFlushData1(tif))
00112                     return (-1);
00113                 op = tif->tif_rawcp;
00114             }
00115         }
00116         switch (state) {
00117         case BASE:      /* initial state, set run/literal */
00118             if (n > 1) {
00119                 state = RUN;
00120                 if (n > 128) {
00121                     *op++ = (tidata) -127;
00122                     *op++ = (tidataval_t) b;
00123                     n -= 128;
00124                     goto again;
00125                 }
00126                 *op++ = (tidataval_t)(-(n-1));
00127                 *op++ = (tidataval_t) b;
00128             } else {
00129                 lastliteral = op;
00130                 *op++ = 0;
00131                 *op++ = (tidataval_t) b;
00132                 state = LITERAL;
00133             }
00134             break;
00135         case LITERAL:       /* last object was literal string */
00136             if (n > 1) {
00137                 state = LITERAL_RUN;
00138                 if (n > 128) {
00139                     *op++ = (tidata) -127;
00140                     *op++ = (tidataval_t) b;
00141                     n -= 128;
00142                     goto again;
00143                 }
00144                 *op++ = (tidataval_t)(-(n-1));  /* encode run */
00145                 *op++ = (tidataval_t) b;
00146             } else {            /* extend literal */
00147                 if (++(*lastliteral) == 127)
00148                     state = BASE;
00149                 *op++ = (tidataval_t) b;
00150             }
00151             break;
00152         case RUN:       /* last object was run */
00153             if (n > 1) {
00154                 if (n > 128) {
00155                     *op++ = (tidata) -127;
00156                     *op++ = (tidataval_t) b;
00157                     n -= 128;
00158                     goto again;
00159                 }
00160                 *op++ = (tidataval_t)(-(n-1));
00161                 *op++ = (tidataval_t) b;
00162             } else {
00163                 lastliteral = op;
00164                 *op++ = 0;
00165                 *op++ = (tidataval_t) b;
00166                 state = LITERAL;
00167             }
00168             break;
00169         case LITERAL_RUN:   /* literal followed by a run */
00170             /*
00171              * Check to see if previous run should
00172              * be converted to a literal, in which
00173              * case we convert literal-run-literal
00174              * to a single literal.
00175              */
00176             if (n == 1 && op[-2] == (tidata) -1 &&
00177                 *lastliteral < 126) {
00178                 state = (((*lastliteral) += 2) == 127 ?
00179                     BASE : LITERAL);
00180                 op[-2] = op[-1];    /* replicate */
00181             } else
00182                 state = RUN;
00183             goto again;
00184         }
00185     }
00186     tif->tif_rawcc += op - tif->tif_rawcp;
00187     tif->tif_rawcp = op;
00188     return (1);
00189 }
00190 
00191 /*
00192  * Encode a rectangular chunk of pixels.  We break it up
00193  * into row-sized pieces to insure that encoded runs do
00194  * not span rows.  Otherwise, there can be problems with
00195  * the decoder if data is read, for example, by scanlines
00196  * when it was encoded by strips.
00197  */
00198 static int
00199 PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
00200 {
00201     tsize_t rowsize = *(tsize_t*)tif->tif_data;
00202 
00203     while ((long)cc > 0) {
00204         int chunk = rowsize;
00205         
00206         if( cc < chunk )
00207             chunk = cc;
00208 
00209         if (PackBitsEncode(tif, bp, chunk, s) < 0)
00210             return (-1);
00211         bp += chunk;
00212         cc -= chunk;
00213     }
00214     return (1);
00215 }
00216 
00217 static int
00218 PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
00219 {
00220     char *bp;
00221     tsize_t cc;
00222     long n;
00223     int b;
00224 
00225     (void) s;
00226     bp = (char*) tif->tif_rawcp;
00227     cc = tif->tif_rawcc;
00228     while (cc > 0 && (long)occ > 0) {
00229         n = (long) *bp++, cc--;
00230         /*
00231          * Watch out for compilers that
00232          * don't sign extend chars...
00233          */
00234         if (n >= 128)
00235             n -= 256;
00236         if (n < 0) {        /* replicate next byte -n+1 times */
00237             if (n == -128)  /* nop */
00238                 continue;
00239                         n = -n + 1;
00240                         if( occ < n )
00241                         {
00242                             TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
00243                                         "PackBitsDecode: discarding %ld bytes "
00244                                         "to avoid buffer overrun",
00245                                         n - occ);
00246                             n = occ;
00247                         }
00248             occ -= n;
00249             b = *bp++, cc--;
00250             while (n-- > 0)
00251                 *op++ = (tidataval_t) b;
00252         } else {        /* copy next n+1 bytes literally */
00253             if (occ < n + 1)
00254                         {
00255                             TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
00256                                         "PackBitsDecode: discarding %ld bytes "
00257                                         "to avoid buffer overrun",
00258                                         n - occ + 1);
00259                             n = occ - 1;
00260                         }
00261                         _TIFFmemcpy(op, bp, ++n);
00262             op += n; occ -= n;
00263             bp += n; cc -= n;
00264         }
00265     }
00266     tif->tif_rawcp = (tidata_t) bp;
00267     tif->tif_rawcc = cc;
00268     if (occ > 0) {
00269         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
00270             "PackBitsDecode: Not enough data for scanline %ld",
00271             (long) tif->tif_row);
00272         return (0);
00273     }
00274     return (1);
00275 }
00276 
00277 int
00278 TIFFInitPackBits(TIFF* tif, int scheme)
00279 {
00280     (void) scheme;
00281     tif->tif_decoderow = PackBitsDecode;
00282     tif->tif_decodestrip = PackBitsDecode;
00283     tif->tif_decodetile = PackBitsDecode;
00284     tif->tif_preencode = PackBitsPreEncode;
00285         tif->tif_postencode = PackBitsPostEncode;
00286     tif->tif_encoderow = PackBitsEncode;
00287     tif->tif_encodestrip = PackBitsEncodeChunk;
00288     tif->tif_encodetile = PackBitsEncodeChunk;
00289     return (1);
00290 }
00291 #endif /* PACKBITS_SUPPORT */
00292 
00293 /* vim: set ts=8 sts=8 sw=8 noet: */
00294 /*
00295  * Local Variables:
00296  * mode: c
00297  * c-basic-offset: 8
00298  * fill-column: 78
00299  * End:
00300  */

Generated on Sun May 27 2012 04:19:35 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.