PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - gd/libgd - gd_gif_out.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 250
Code covered: 87.2 % Executed lines: 218
Legend: not executed executed

       1                 : #include <stdio.h>
       2                 : #include <math.h>
       3                 : #include <string.h>
       4                 : #include <stdlib.h>
       5                 : #include "gd.h"
       6                 : 
       7                 : /* Code drawn from ppmtogif.c, from the pbmplus package
       8                 : **
       9                 : ** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
      10                 : ** Lempel-Zim compression based on "compress".
      11                 : **
      12                 : ** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
      13                 : **
      14                 : ** Copyright (C) 1989 by Jef Poskanzer.
      15                 : **
      16                 : ** Permission to use, copy, modify, and distribute this software and its
      17                 : ** documentation for any purpose and without fee is hereby granted, provided
      18                 : ** that the above copyright notice appear in all copies and that both that
      19                 : ** copyright notice and this permission notice appear in supporting
      20                 : ** documentation.  This software is provided "as is" without express or
      21                 : ** implied warranty.
      22                 : **
      23                 : ** The Graphics Interchange Format(c) is the Copyright property of
      24                 : ** CompuServe Incorporated.  GIF(sm) is a Service Mark property of
      25                 : ** CompuServe Incorporated.
      26                 : */
      27                 : 
      28                 : /*
      29                 :  * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
      30                 :  */
      31                 : typedef int             code_int;
      32                 : 
      33                 : #ifdef SIGNED_COMPARE_SLOW
      34                 : typedef unsigned long int count_int;
      35                 : typedef unsigned short int count_short;
      36                 : #else /*SIGNED_COMPARE_SLOW*/
      37                 : typedef long int          count_int;
      38                 : #endif /*SIGNED_COMPARE_SLOW*/
      39                 : 
      40                 : /* 2.0.28: threadsafe */
      41                 : 
      42                 : #define maxbits GIFBITS
      43                 : 
      44                 : /* should NEVER generate this code */
      45                 : #define maxmaxcode ((code_int)1 << GIFBITS)
      46                 : 
      47                 : #define HSIZE  5003            /* 80% occupancy */
      48                 : #define hsize HSIZE            /* Apparently invariant, left over from 
      49                 :                                         compress */
      50                 : 
      51                 : typedef struct {
      52                 :         int Width, Height;
      53                 :         int curx, cury;
      54                 :         long CountDown;
      55                 :         int Pass;
      56                 :         int Interlace;
      57                 :         int n_bits;                        /* number of bits/code */
      58                 :         code_int maxcode;                  /* maximum code, given n_bits */
      59                 :         count_int htab [HSIZE];
      60                 :         unsigned short codetab [HSIZE];
      61                 :         code_int free_ent;                  /* first unused entry */
      62                 :         /*
      63                 :          * block compression parameters -- after all codes are used up,
      64                 :          * and compression rate changes, start over.
      65                 :          */
      66                 :         int clear_flg;
      67                 :         int offset;
      68                 :         long int in_count;            /* length of input */
      69                 :         long int out_count;           /* # of codes output (for debugging) */
      70                 : 
      71                 :         int g_init_bits;
      72                 :         gdIOCtx * g_outfile;
      73                 : 
      74                 :         int ClearCode;
      75                 :         int EOFCode;
      76                 :         unsigned long cur_accum;
      77                 :         int cur_bits;
      78                 :         /*
      79                 :          * Number of characters so far in this 'packet'
      80                 :          */
      81                 :         int a_count;
      82                 :         /*
      83                 :          * Define the storage for the packet accumulator
      84                 :          */
      85                 :         char accum[ 256 ];
      86                 : } GifCtx;
      87                 : 
      88                 : static int gifPutWord(int w, gdIOCtx *out);
      89                 : static int colorstobpp(int colors);
      90                 : static void BumpPixel (GifCtx *ctx);
      91                 : static int GIFNextPixel (gdImagePtr im, GifCtx *ctx);
      92                 : static void GIFEncode (gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
      93                 : static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im, GifCtx *ctx);
      94                 : static void output (code_int code, GifCtx *ctx);
      95                 : static void cl_block (GifCtx *ctx);
      96                 : static void cl_hash (register count_int chsize, GifCtx *ctx);
      97                 : static void char_init (GifCtx *ctx);
      98                 : static void char_out (int c, GifCtx *ctx);
      99                 : static void flush_char (GifCtx *ctx);
     100                 : void * gdImageGifPtr (gdImagePtr im, int *size)
     101               0 : {
     102                 :   void *rv;
     103               0 :   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
     104               0 :   gdImageGifCtx (im, out);
     105               0 :   rv = gdDPExtractData (out, size);
     106               0 :   out->gd_free (out);
     107               0 :   return rv;
     108                 : }
     109                 : 
     110                 : void gdImageGif (gdImagePtr im, FILE * outFile)
     111               0 : {
     112               0 :   gdIOCtx *out = gdNewFileCtx (outFile);
     113               0 :   gdImageGifCtx (im, out);
     114               0 :   out->gd_free (out);
     115               0 : }
     116                 : 
     117                 : void gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
     118              11 : {
     119              11 :         gdImagePtr pim = 0, tim = im;
     120                 :         int interlace, transparent, BitsPerPixel;
     121              11 :         interlace = im->interlace;
     122              11 :         transparent = im->transparent;
     123              11 :         if (im->trueColor) {
     124                 :                 /* Expensive, but the only way that produces an
     125                 :                         acceptable result: mix down to a palette
     126                 :                         based temporary image. */
     127               4 :                 pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);
     128               4 :                 if (!pim) {
     129               0 :                         return;
     130                 :                 }
     131               4 :                 tim = pim; 
     132                 :         }
     133              11 :         BitsPerPixel = colorstobpp(tim->colorsTotal);
     134                 :         /* All set, let's do it. */
     135              11 :         GIFEncode(
     136                 :                 out, tim->sx, tim->sy, tim->interlace, 0, tim->transparent, BitsPerPixel,
     137                 :                 tim->red, tim->green, tim->blue, tim);
     138              11 :         if (pim) {
     139                 :                 /* Destroy palette based temporary image. */
     140               4 :                 gdImageDestroy( pim);
     141                 :         }
     142                 : }
     143                 : 
     144                 : static int
     145                 : colorstobpp(int colors)
     146              11 : {
     147              11 :     int bpp = 0;
     148                 : 
     149              11 :     if ( colors <= 2 )
     150               3 :         bpp = 1;
     151               8 :     else if ( colors <= 4 )
     152               0 :         bpp = 2;
     153               8 :     else if ( colors <= 8 )
     154               1 :         bpp = 3;
     155               7 :     else if ( colors <= 16 )
     156               1 :         bpp = 4;
     157               6 :     else if ( colors <= 32 )
     158               1 :         bpp = 5;
     159               5 :     else if ( colors <= 64 )
     160               1 :         bpp = 6;
     161               4 :     else if ( colors <= 128 )
     162               1 :         bpp = 7;
     163               3 :     else if ( colors <= 256 )
     164               3 :         bpp = 8;
     165              11 :     return bpp;
     166                 :     }
     167                 : 
     168                 : /*****************************************************************************
     169                 :  *
     170                 :  * GIFENCODE.C    - GIF Image compression interface
     171                 :  *
     172                 :  * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
     173                 :  *            BitsPerPixel, Red, Green, Blue, gdImagePtr )
     174                 :  *
     175                 :  *****************************************************************************/
     176                 : 
     177                 : #define TRUE 1
     178                 : #define FALSE 0
     179                 : /*
     180                 :  * Bump the 'curx' and 'cury' to point to the next pixel
     181                 :  */
     182                 : static void
     183                 : BumpPixel(GifCtx *ctx)
     184          138685 : {
     185                 :         /*
     186                 :          * Bump the current X position
     187                 :          */
     188          138685 :         ++(ctx->curx);
     189                 : 
     190                 :         /*
     191                 :          * If we are at the end of a scan line, set curx back to the beginning
     192                 :          * If we are interlaced, bump the cury to the appropriate spot,
     193                 :          * otherwise, just increment it.
     194                 :          */
     195          138685 :         if( ctx->curx == ctx->Width ) {
     196             619 :                 ctx->curx = 0;
     197                 : 
     198             619 :                 if( !ctx->Interlace )
     199             619 :                         ++(ctx->cury);
     200                 :                 else {
     201               0 :                      switch( ctx->Pass ) {
     202                 : 
     203                 :                        case 0:
     204               0 :                           ctx->cury += 8;
     205               0 :                           if( ctx->cury >= ctx->Height ) {
     206               0 :                                 ++(ctx->Pass);
     207               0 :                                 ctx->cury = 4;
     208                 :                           }
     209               0 :                           break;
     210                 : 
     211                 :                        case 1:
     212               0 :                           ctx->cury += 8;
     213               0 :                           if( ctx->cury >= ctx->Height ) {
     214               0 :                                 ++(ctx->Pass);
     215               0 :                                 ctx->cury = 2;
     216                 :                           }
     217               0 :                           break;
     218                 : 
     219                 :                        case 2:
     220               0 :                           ctx->cury += 4;
     221               0 :                           if( ctx->cury >= ctx->Height ) {
     222               0 :                              ++(ctx->Pass);
     223               0 :                              ctx->cury = 1;
     224                 :                           }
     225               0 :                           break;
     226                 : 
     227                 :                        case 3:
     228               0 :                           ctx->cury += 2;
     229                 :                           break;
     230                 :                         }
     231                 :                 }
     232                 :         }
     233          138685 : }
     234                 : 
     235                 : /*
     236                 :  * Return the next pixel from the image
     237                 :  */
     238                 : static int
     239                 : GIFNextPixel(gdImagePtr im, GifCtx *ctx)
     240          138696 : {
     241                 :         int r;
     242                 : 
     243          138696 :         if( ctx->CountDown == 0 )
     244              11 :                 return EOF;
     245                 : 
     246          138685 :         --(ctx->CountDown);
     247                 : 
     248          138685 :         r = gdImageGetPixel(im, ctx->curx, ctx->cury);
     249                 : 
     250          138685 :         BumpPixel(ctx);
     251                 : 
     252          138685 :         return r;
     253                 : }
     254                 : 
     255                 : /* public */
     256                 : 
     257                 : static void
     258                 : GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
     259              11 : {
     260                 :         int B;
     261                 :         int RWidth, RHeight;
     262                 :         int LeftOfs, TopOfs;
     263                 :         int Resolution;
     264                 :         int ColorMapSize;
     265                 :         int InitCodeSize;
     266                 :         int i;
     267                 :                 GifCtx ctx;
     268                 : 
     269              11 :                 memset(&ctx, 0, sizeof(ctx));
     270              11 :         ctx.Interlace = GInterlace;
     271              11 :                 ctx.in_count = 1;
     272                 : 
     273              11 :         ColorMapSize = 1 << BitsPerPixel;
     274                 : 
     275              11 :         RWidth = ctx.Width = GWidth;
     276              11 :         RHeight = ctx.Height = GHeight;
     277              11 :         LeftOfs = TopOfs = 0;
     278                 : 
     279              11 :         Resolution = BitsPerPixel;
     280                 : 
     281                 :         /*
     282                 :          * Calculate number of bits we are expecting
     283                 :          */
     284              11 :         ctx.CountDown = (long)ctx.Width * (long)ctx.Height;
     285                 : 
     286                 :         /*
     287                 :          * Indicate which pass we are on (if interlace)
     288                 :          */
     289              11 :         ctx.Pass = 0;
     290                 : 
     291                 :         /*
     292                 :          * The initial code size
     293                 :          */
     294              11 :         if( BitsPerPixel <= 1 )
     295               3 :                 InitCodeSize = 2;
     296                 :         else
     297               8 :                 InitCodeSize = BitsPerPixel;
     298                 : 
     299                 :         /*
     300                 :          * Set up the current x and y position
     301                 :          */
     302              11 :         ctx.curx = ctx.cury = 0;
     303                 : 
     304                 :         /*
     305                 :          * Write the Magic header
     306                 :          */
     307              11 :         gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );
     308                 : 
     309                 :         /*
     310                 :          * Write out the screen width and height
     311                 :          */
     312              11 :         gifPutWord( RWidth, fp );
     313              11 :         gifPutWord( RHeight, fp );
     314                 : 
     315                 :         /*
     316                 :          * Indicate that there is a global colour map
     317                 :          */
     318              11 :         B = 0x80;       /* Yes, there is a color map */
     319                 : 
     320                 :         /*
     321                 :          * OR in the resolution
     322                 :          */
     323              11 :         B |= (Resolution - 1) << 5;
     324                 : 
     325                 :         /*
     326                 :          * OR in the Bits per Pixel
     327                 :          */
     328              11 :         B |= (BitsPerPixel - 1);
     329                 : 
     330                 :         /*
     331                 :          * Write it out
     332                 :          */
     333              11 :         gdPutC( B, fp );
     334                 : 
     335                 :         /*
     336                 :          * Write out the Background colour
     337                 :          */
     338              11 :         gdPutC( Background, fp );
     339                 : 
     340                 :         /*
     341                 :          * Byte of 0's (future expansion)
     342                 :          */
     343              11 :         gdPutC( 0, fp );
     344                 : 
     345                 :         /*
     346                 :          * Write out the Global Colour Map
     347                 :          */
     348            1033 :         for( i=0; i<ColorMapSize; ++i ) {
     349            1022 :                 gdPutC( Red[i], fp );
     350            1022 :                 gdPutC( Green[i], fp );
     351            1022 :                 gdPutC( Blue[i], fp );
     352                 :         }
     353                 : 
     354                 :         /*
     355                 :          * Write out extension for transparent colour index, if necessary.
     356                 :          */
     357              11 :         if ( Transparent >= 0 ) {
     358               1 :             gdPutC( '!', fp );
     359               1 :             gdPutC( 0xf9, fp );
     360               1 :             gdPutC( 4, fp );
     361               1 :             gdPutC( 1, fp );
     362               1 :             gdPutC( 0, fp );
     363               1 :             gdPutC( 0, fp );
     364               1 :             gdPutC( (unsigned char) Transparent, fp );
     365               1 :             gdPutC( 0, fp );
     366                 :         }
     367                 : 
     368                 :         /*
     369                 :          * Write an Image separator
     370                 :          */
     371              11 :         gdPutC( ',', fp );
     372                 : 
     373                 :         /*
     374                 :          * Write the Image header
     375                 :          */
     376                 : 
     377              11 :         gifPutWord( LeftOfs, fp );
     378              11 :         gifPutWord( TopOfs, fp );
     379              11 :         gifPutWord( ctx.Width, fp );
     380              11 :         gifPutWord( ctx.Height, fp );
     381                 : 
     382                 :         /*
     383                 :          * Write out whether or not the image is interlaced
     384                 :          */
     385              11 :         if( ctx.Interlace )
     386               0 :                 gdPutC( 0x40, fp );
     387                 :         else
     388              11 :                 gdPutC( 0x00, fp );
     389                 : 
     390                 :         /*
     391                 :          * Write out the initial code size
     392                 :          */
     393              11 :         gdPutC( InitCodeSize, fp );
     394                 : 
     395                 :         /*
     396                 :          * Go and actually compress the data
     397                 :          */
     398              11 :         compress( InitCodeSize+1, fp, im, &ctx );
     399                 : 
     400                 :         /*
     401                 :          * Write out a Zero-length packet (to end the series)
     402                 :          */
     403              11 :         gdPutC( 0, fp );
     404                 : 
     405                 :         /*
     406                 :          * Write the GIF file terminator
     407                 :          */
     408              11 :         gdPutC( ';', fp );
     409              11 : }
     410                 : 
     411                 : /***************************************************************************
     412                 :  *
     413                 :  *  GIFCOMPR.C       - GIF Image compression routines
     414                 :  *
     415                 :  *  Lempel-Ziv compression based on 'compress'.  GIF modifications by
     416                 :  *  David Rowley (mgardi@watdcsu.waterloo.edu)
     417                 :  *
     418                 :  ***************************************************************************/
     419                 : 
     420                 : /*
     421                 :  * General DEFINEs
     422                 :  */
     423                 : 
     424                 : #define GIFBITS    12
     425                 : 
     426                 : #ifdef NO_UCHAR
     427                 :  typedef char   char_type;
     428                 : #else /*NO_UCHAR*/
     429                 :  typedef        unsigned char   char_type;
     430                 : #endif /*NO_UCHAR*/
     431                 : 
     432                 : /*
     433                 :  *
     434                 :  * GIF Image compression - modified 'compress'
     435                 :  *
     436                 :  * Based on: compress.c - File compression ala IEEE Computer, June 1984.
     437                 :  *
     438                 :  * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
     439                 :  *              Jim McKie               (decvax!mcvax!jim)
     440                 :  *              Steve Davies            (decvax!vax135!petsd!peora!srd)
     441                 :  *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
     442                 :  *              James A. Woods          (decvax!ihnp4!ames!jaw)
     443                 :  *              Joe Orost               (decvax!vax135!petsd!joe)
     444                 :  *
     445                 :  */
     446                 : #include <ctype.h>
     447                 : 
     448                 : #define ARGVAL() (*++(*argv) || (--argc && *++argv))
     449                 : 
     450                 : #ifdef COMPATIBLE               /* But wrong! */
     451                 : # define MAXCODE(n_bits)        ((code_int) 1 << (n_bits) - 1)
     452                 : #else /*COMPATIBLE*/
     453                 : # define MAXCODE(n_bits)        (((code_int) 1 << (n_bits)) - 1)
     454                 : #endif /*COMPATIBLE*/
     455                 : 
     456                 : #define HashTabOf(i)       ctx->htab[i]
     457                 : #define CodeTabOf(i)    ctx->codetab[i]
     458                 : 
     459                 : 
     460                 : /*
     461                 :  * To save much memory, we overlay the table used by compress() with those
     462                 :  * used by decompress().  The tab_prefix table is the same size and type
     463                 :  * as the codetab.  The tab_suffix table needs 2**GIFBITS characters.  We
     464                 :  * get this from the beginning of htab.  The output stack uses the rest
     465                 :  * of htab, and contains characters.  There is plenty of room for any
     466                 :  * possible stack (stack used to be 8000 characters).
     467                 :  */
     468                 : 
     469                 : #define tab_prefixof(i) CodeTabOf(i)
     470                 : #define tab_suffixof(i)        ((char_type*)(htab))[i]
     471                 : #define de_stack               ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
     472                 : 
     473                 : /*
     474                 :  * compress stdin to stdout
     475                 :  *
     476                 :  * Algorithm:  use open addressing double hashing (no chaining) on the
     477                 :  * prefix code / next character combination.  We do a variant of Knuth's
     478                 :  * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
     479                 :  * secondary probe.  Here, the modular division first probe is gives way
     480                 :  * to a faster exclusive-or manipulation.  Also do block compression with
     481                 :  * an adaptive reset, whereby the code table is cleared when the compression
     482                 :  * ratio decreases, but after the table fills.  The variable-length output
     483                 :  * codes are re-sized at this point, and a special CLEAR code is generated
     484                 :  * for the decompressor.  Late addition:  construct the table according to
     485                 :  * file size for noticeable speed improvement on small files.  Please direct
     486                 :  * questions about this implementation to ames!jaw.
     487                 :  */
     488                 : 
     489                 : static void
     490                 : output(code_int code, GifCtx *ctx);
     491                 : 
     492                 : static void
     493                 : compress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *ctx)
     494              11 : {
     495                 :     register long fcode;
     496                 :     register code_int i /* = 0 */;
     497                 :     register int c;
     498                 :     register code_int ent;
     499                 :     register code_int disp;
     500                 :     register code_int hsize_reg;
     501                 :     register int hshift;
     502                 : 
     503                 :     /*
     504                 :      * Set up the globals:  g_init_bits - initial number of bits
     505                 :      *                      g_outfile   - pointer to output file
     506                 :      */
     507              11 :     ctx->g_init_bits = init_bits;
     508              11 :     ctx->g_outfile = outfile;
     509                 : 
     510                 :     /*
     511                 :      * Set up the necessary values
     512                 :      */
     513              11 :     ctx->offset = 0;
     514              11 :     ctx->out_count = 0;
     515              11 :     ctx->clear_flg = 0;
     516              11 :     ctx->in_count = 1;
     517              11 :     ctx->maxcode = MAXCODE(ctx->n_bits = ctx->g_init_bits);
     518                 : 
     519              11 :     ctx->ClearCode = (1 << (init_bits - 1));
     520              11 :     ctx->EOFCode = ctx->ClearCode + 1;
     521              11 :     ctx->free_ent = ctx->ClearCode + 2;
     522                 : 
     523              11 :     char_init(ctx);
     524                 : 
     525              11 :     ent = GIFNextPixel( im, ctx );
     526                 : 
     527              11 :     hshift = 0;
     528              55 :     for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
     529              44 :         ++hshift;
     530              11 :     hshift = 8 - hshift;                /* set hash code range bound */
     531                 : 
     532              11 :     hsize_reg = hsize;
     533              11 :     cl_hash( (count_int) hsize_reg, ctx );            /* clear hash table */
     534                 : 
     535              11 :     output( (code_int)ctx->ClearCode, ctx );
     536                 : 
     537                 : #ifdef SIGNED_COMPARE_SLOW
     538                 :     while ( (c = GIFNextPixel( im )) != (unsigned) EOF ) {
     539                 : #else /*SIGNED_COMPARE_SLOW*/
     540          138696 :     while ( (c = GIFNextPixel( im, ctx )) != EOF ) {  /* } */
     541                 : #endif /*SIGNED_COMPARE_SLOW*/
     542                 : 
     543          138674 :         ++(ctx->in_count);
     544                 : 
     545          138674 :         fcode = (long) (((long) c << maxbits) + ent);
     546          138674 :         i = (((code_int)c << hshift) ^ ent);    /* xor hashing */
     547                 : 
     548          138674 :         if ( HashTabOf (i) == fcode ) {
     549           69322 :             ent = CodeTabOf (i);
     550           69322 :             continue;
     551           69352 :         } else if ( (long)HashTabOf (i) < 0 )      /* empty slot */
     552           26482 :             goto nomatch;
     553           42870 :         disp = hsize_reg - i;           /* secondary hash (after G. Knott) */
     554           42870 :         if ( i == 0 )
     555               0 :             disp = 1;
     556          116762 : probe:
     557          116762 :         if ( (i -= disp) < 0 )
     558           82592 :             i += hsize_reg;
     559                 : 
     560          116762 :         if ( HashTabOf (i) == fcode ) {
     561           22552 :             ent = CodeTabOf (i);
     562           22552 :             continue;
     563                 :         }
     564           94210 :         if ( (long)HashTabOf (i) > 0 )
     565           73892 :             goto probe;
     566           46800 : nomatch:
     567           46800 :         output ( (code_int) ent, ctx );
     568           46800 :         ++(ctx->out_count);
     569           46800 :         ent = c;
     570                 : #ifdef SIGNED_COMPARE_SLOW
     571                 :         if ( (unsigned) ctx->free_ent < (unsigned) maxmaxcode) {
     572                 : #else /*SIGNED_COMPARE_SLOW*/
     573           46800 :         if ( ctx->free_ent < maxmaxcode ) {  /* } */
     574                 : #endif /*SIGNED_COMPARE_SLOW*/
     575           46788 :             CodeTabOf (i) = ctx->free_ent++; /* code -> hashtable */
     576           46788 :             HashTabOf (i) = fcode;
     577                 :         } else
     578              12 :                 cl_block(ctx);
     579                 :     }
     580                 :     /*
     581                 :      * Put out the final code.
     582                 :      */
     583              11 :     output( (code_int)ent, ctx );
     584              11 :     ++(ctx->out_count);
     585              11 :     output( (code_int) ctx->EOFCode, ctx );
     586              11 : }
     587                 : 
     588                 : /*****************************************************************
     589                 :  * TAG( output )
     590                 :  *
     591                 :  * Output the given code.
     592                 :  * Inputs:
     593                 :  *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
     594                 :  *              that n_bits =< (long)wordsize - 1.
     595                 :  * Outputs:
     596                 :  *      Outputs code to the file.
     597                 :  * Assumptions:
     598                 :  *      Chars are 8 bits long.
     599                 :  * Algorithm:
     600                 :  *      Maintain a GIFBITS character long buffer (so that 8 codes will
     601                 :  * fit in it exactly).  Use the VAX insv instruction to insert each
     602                 :  * code in turn.  When the buffer fills up empty it and start over.
     603                 :  */
     604                 : 
     605                 : static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
     606                 :                                   0x001F, 0x003F, 0x007F, 0x00FF,
     607                 :                                   0x01FF, 0x03FF, 0x07FF, 0x0FFF,
     608                 :                                   0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
     609                 : 
     610                 : static void
     611                 : output(code_int code, GifCtx *ctx)
     612           46845 : {
     613           46845 :     ctx->cur_accum &= masks[ ctx->cur_bits ];
     614                 : 
     615           46845 :     if( ctx->cur_bits > 0 )
     616           39921 :         ctx->cur_accum |= ((long)code << ctx->cur_bits);
     617                 :     else
     618            6924 :         ctx->cur_accum = code;
     619                 : 
     620           46845 :     ctx->cur_bits += ctx->n_bits;
     621                 : 
     622          159349 :     while( ctx->cur_bits >= 8 ) {
     623           65659 :         char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx );
     624           65659 :         ctx->cur_accum >>= 8;
     625           65659 :         ctx->cur_bits -= 8;
     626                 :     }
     627                 : 
     628                 :     /*
     629                 :      * If the next entry is going to be too big for the code size,
     630                 :      * then increase it, if possible.
     631                 :      */
     632           46845 :    if ( ctx->free_ent > ctx->maxcode || ctx->clear_flg ) {
     633                 : 
     634              57 :             if( ctx->clear_flg ) {
     635                 : 
     636              12 :                 ctx->maxcode = MAXCODE (ctx->n_bits = ctx->g_init_bits);
     637              12 :                 ctx->clear_flg = 0;
     638                 : 
     639                 :             } else {
     640                 : 
     641              45 :                 ++(ctx->n_bits);
     642              45 :                 if ( ctx->n_bits == maxbits )
     643              12 :                     ctx->maxcode = maxmaxcode;
     644                 :                 else
     645              33 :                     ctx->maxcode = MAXCODE(ctx->n_bits);
     646                 :             }
     647                 :         }
     648                 : 
     649           46845 :     if( code == ctx->EOFCode ) {
     650                 :         /*
     651                 :          * At EOF, write the rest of the buffer.
     652                 :          */
     653              28 :         while( ctx->cur_bits > 0 ) {
     654               6 :                 char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx);
     655               6 :                 ctx->cur_accum >>= 8;
     656               6 :                 ctx->cur_bits -= 8;
     657                 :         }
     658                 : 
     659              11 :         flush_char(ctx);
     660                 : 
     661                 :     }
     662           46845 : }
     663                 : 
     664                 : /*
     665                 :  * Clear out the hash table
     666                 :  */
     667                 : static void
     668                 : cl_block (GifCtx *ctx)             /* table clear for block compress */
     669              12 : {
     670                 : 
     671              12 :         cl_hash ( (count_int) hsize, ctx );
     672              12 :         ctx->free_ent = ctx->ClearCode + 2;
     673              12 :         ctx->clear_flg = 1;
     674                 : 
     675              12 :         output( (code_int)ctx->ClearCode, ctx);
     676              12 : }
     677                 : 
     678                 : static void
     679                 : cl_hash(register count_int chsize, GifCtx *ctx)          /* reset code table */
     680                 :                          
     681              23 : {
     682                 : 
     683              23 :         register count_int *htab_p = ctx->htab+chsize;
     684                 : 
     685                 :         register long i;
     686              23 :         register long m1 = -1;
     687                 : 
     688              23 :         i = chsize - 16;
     689                 :         do {                            /* might use Sys V memset(3) here */
     690            7176 :                 *(htab_p-16) = m1;
     691            7176 :                 *(htab_p-15) = m1;
     692            7176 :                 *(htab_p-14) = m1;
     693            7176 :                 *(htab_p-13) = m1;
     694            7176 :                 *(htab_p-12) = m1;
     695            7176 :                 *(htab_p-11) = m1;
     696            7176 :                 *(htab_p-10) = m1;
     697            7176 :                 *(htab_p-9) = m1;
     698            7176 :                 *(htab_p-8) = m1;
     699            7176 :                 *(htab_p-7) = m1;
     700            7176 :                 *(htab_p-6) = m1;
     701            7176 :                 *(htab_p-5) = m1;
     702            7176 :                 *(htab_p-4) = m1;
     703            7176 :                 *(htab_p-3) = m1;
     704            7176 :                 *(htab_p-2) = m1;
     705            7176 :                 *(htab_p-1) = m1;
     706            7176 :                 htab_p -= 16;
     707            7176 :         } while ((i -= 16) >= 0);
     708                 : 
     709             276 :         for ( i += 16; i > 0; --i )
     710             253 :                 *--htab_p = m1;
     711              23 : }
     712                 : 
     713                 : /******************************************************************************
     714                 :  *
     715                 :  * GIF Specific routines
     716                 :  *
     717                 :  ******************************************************************************/
     718                 : 
     719                 : /*
     720                 :  * Set up the 'byte output' routine
     721                 :  */
     722                 : static void
     723                 : char_init(GifCtx *ctx)
     724              11 : {
     725              11 :         ctx->a_count = 0;
     726              11 : }
     727                 : 
     728                 : /*
     729                 :  * Add a character to the end of the current packet, and if it is 254
     730                 :  * characters, flush the packet to disk.
     731                 :  */
     732                 : static void
     733                 : char_out(int c, GifCtx *ctx)
     734           65665 : {
     735           65665 :         ctx->accum[ ctx->a_count++ ] = c;
     736           65665 :         if( ctx->a_count >= 254 )
     737             256 :                 flush_char(ctx);
     738           65665 : }
     739                 : 
     740                 : /*
     741                 :  * Flush the packet to disk, and reset the accumulator
     742                 :  */
     743                 : static void
     744                 : flush_char(GifCtx *ctx)
     745             267 : {
     746             267 :         if( ctx->a_count > 0 ) {
     747             267 :                 gdPutC( ctx->a_count, ctx->g_outfile );
     748             267 :                 gdPutBuf( ctx->accum, ctx->a_count, ctx->g_outfile );
     749             267 :                 ctx->a_count = 0;
     750                 :         }
     751             267 : }
     752                 : 
     753                 : static int gifPutWord(int w, gdIOCtx *out)
     754              66 : {
     755                 :         /* Byte order is little-endian */
     756              66 :         gdPutC(w & 0xFF, out);
     757              66 :         gdPutC((w >> 8) & 0xFF, out);
     758              66 :         return 0;
     759                 : }
     760                 : 
     761                 : 

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:07 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.