Changeset 128


Ignore:
Timestamp:
Mar 22, 2008, 9:39:01 AM (14 years ago)
Author:
Sam Hocevar
Message:
  • Minor refactoring in imlib.
Location:
abuse/trunk/src/imlib
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/src/imlib/decoder.cpp

    r124 r128  
    6060
    6161/* Static variables */
    62 short curr_size;                    /* The current code size */
    63 short clear;                         /* Value for a clear code */
    64 short ending;                        /* Value for a ending code */
    65 short newcodes;                      /* First available code */
    66 short top_slot;                      /* Highest code for current size */
    67 short slot;                          /* Last read code */
     62static int16_t curr_size; /* The current code size */
     63static int16_t clear;     /* Value for a clear code */
     64static int16_t ending;    /* Value for a ending code */
     65static int16_t newcodes;  /* First available code */
     66static int16_t top_slot;  /* Highest code for current size */
     67static int16_t slot;      /* Last read code */
    6868
    6969/* The following static variables are used
    70  * for separating out codes
    71  */
    72 short navail_bytes = 0;              /* # bytes left in block */
    73 short nbits_left = 0;                /* # bits left in current byte */
    74   unsigned char b1;                           /* Current byte */
    75   unsigned char byte_buff[257];               /* Current block */
    76   unsigned char *pbytes;                      /* Pointer to next byte in block */
    77 
    78   long code_mask[13] = {
    79      0,
    80      0x0001, 0x0003,
    81      0x0007, 0x000F,
    82      0x001F, 0x003F,
    83      0x007F, 0x00FF,
    84      0x01FF, 0x03FF,
    85      0x07FF, 0x0FFF
    86      };
    87 
    88 
    89 /* This function initializes the decoder for reading a new image.
    90  */
    91 short init_exp(short size)
    92    {
    93    curr_size = size + 1;
    94    top_slot = 1 << curr_size;
    95    clear = 1 << size;
    96    ending = clear + 1;
    97    slot = newcodes = ending + 1;
    98    navail_bytes = nbits_left = 0;
    99    return(0);
    100    }
     70 * for separating out codes */
     71static int16_t navail_bytes = 0; /* # bytes left in block */
     72static int16_t nbits_left = 0;   /* # bits left in current byte */
     73static uint8_t b1;               /* Current byte */
     74static uint8_t byte_buff[257];   /* Current block */
     75static uint8_t *pbytes;          /* Pointer to next byte in block */
     76
     77static int32_t code_mask[13] =
     78{
     79    0,
     80    0x0001, 0x0003,
     81    0x0007, 0x000F,
     82    0x001F, 0x003F,
     83    0x007F, 0x00FF,
     84    0x01FF, 0x03FF,
     85    0x07FF, 0x0FFF
     86};
     87
     88/* This function initializes the decoder for reading a new image. */
     89int16_t init_exp(int16_t size)
     90{
     91    curr_size = size + 1;
     92    top_slot = 1 << curr_size;
     93    clear = 1 << size;
     94    ending = clear + 1;
     95    slot = newcodes = ending + 1;
     96    navail_bytes = nbits_left = 0;
     97    return 0;
     98}
    10199
    102100/* get_next_code()
    103101 * - gets the next code from the GIF file.  Returns the code, or else
    104  * a negative number in case of file errors...
    105  */
    106 
    107 short int get_byte()
    108 {
    109   short int x=0;
    110   if (fread(&x,1,1,ufp)!=1)
    111     return READ_ERROR;
    112   else return x;
     102 * a negative number in case of file errors... */
     103int16_t get_byte()
     104{
     105    int8_t x = 0;
     106
     107    if(fread(&x, 1, 1, ufp) != 1)
     108        return READ_ERROR;
     109
     110    return x;
    113111}
    114112
    115 short get_next_code()
    116    {
    117    short i, x;
    118    unsigned long ret;
    119 
    120    if (nbits_left == 0)
    121       {
    122       if (navail_bytes <= 0)
    123      {
    124 
    125      /* Out of bytes in current block, so read next block
    126       */
    127      pbytes = byte_buff;
    128      if ((navail_bytes = get_byte()) < 0)
    129         return(navail_bytes);
    130      else if (navail_bytes)
    131         {
    132         for (i = 0; i < navail_bytes; ++i)
    133            {
    134            if ((x = get_byte()) < 0)
    135           return(x);
    136            byte_buff[i] = x;
    137            }
    138         }
    139      }
    140       b1 = *pbytes++;
    141       nbits_left = 8;
    142       --navail_bytes;
    143       }
    144 
    145    ret = b1 >> (8 - nbits_left);
    146    while (curr_size > nbits_left)
    147       {
    148       if (navail_bytes <= 0)
    149      {
    150 
    151      /* Out of bytes in current block, so read next block
    152       */
    153      pbytes = byte_buff;
    154      if ((navail_bytes = get_byte()) < 0)
    155         return(navail_bytes);
    156      else if (navail_bytes)
    157         {
    158         for (i = 0; i < navail_bytes; ++i)
    159            {
    160            if ((x = get_byte()) < 0)
    161           return(x);
    162            byte_buff[i] = x;
    163            }
    164         }
    165      }
    166       b1 = *pbytes++;
    167       ret |= b1 << nbits_left;
    168       nbits_left += 8;
    169       --navail_bytes;
    170       }
    171    nbits_left -= curr_size;
    172    ret &= code_mask[curr_size];
    173    return((short)(ret));
    174    }
     113int16_t get_next_code()
     114{
     115    int16_t i, x;
     116    uint32_t ret;
     117
     118    if (nbits_left == 0)
     119    {
     120        if (navail_bytes <= 0)
     121        {
     122            /* Out of bytes in current block, so read next block */
     123            pbytes = byte_buff;
     124            if ((navail_bytes = get_byte()) < 0)
     125               return navail_bytes;
     126            else if (navail_bytes)
     127            {
     128                for (i = 0; i < navail_bytes; ++i)
     129                {
     130                    if ((x = get_byte()) < 0)
     131                        return x;
     132                    byte_buff[i] = x;
     133                }
     134            }
     135        }
     136
     137        b1 = *pbytes++;
     138        nbits_left = 8;
     139        --navail_bytes;
     140    }
     141
     142    ret = b1 >> (8 - nbits_left);
     143    while (curr_size > nbits_left)
     144    {
     145        if (navail_bytes <= 0)
     146        {
     147            /* Out of bytes in current block, so read next block */
     148            pbytes = byte_buff;
     149            if((navail_bytes = get_byte()) < 0)
     150                return navail_bytes;
     151
     152            if(navail_bytes)
     153            {
     154                for (i = 0; i < navail_bytes; ++i)
     155                {
     156                    if ((x = get_byte()) < 0)
     157                        return x;
     158                    byte_buff[i] = x;
     159                }
     160            }
     161        }
     162        b1 = *pbytes++;
     163        ret |= b1 << nbits_left;
     164        nbits_left += 8;
     165        --navail_bytes;
     166    }
     167
     168    nbits_left -= curr_size;
     169    ret &= code_mask[curr_size];
     170
     171    return (int16_t)ret;
     172}
    175173
    176174
     
    180178 * This code is full of similar speedups...  (For a good book on writing
    181179 * C for speed or for space optomisation, see Efficient C by Tom Plum,
    182  * published by Plum-Hall Associates...)
    183  */
    184   unsigned char stack[MAX_CODES + 1];            /* Stack for storing pixels */
    185   unsigned char suffix[MAX_CODES + 1];           /* Suffix table */
    186   unsigned short prefix[MAX_CODES + 1];           /* Prefix linked list */
    187 
    188 /* short decoder(linewidth)
    189  *    short linewidth;               * Pixels per line of image *
     180 * published by Plum-Hall Associates...) */
     181static uint8_t stack[MAX_CODES + 1];   /* Stack for storing pixels */
     182static uint8_t suffix[MAX_CODES + 1];  /* Suffix table */
     183static uint16_t prefix[MAX_CODES + 1]; /* Prefix linked list */
     184
     185/* int16_t decoder(linewidth)
     186 *    int16_t linewidth;               * Pixels per line of image *
    190187 *
    191188 * - This function decodes an LZW image, according to the method used
     
    201198 * code a bit simpler, but it isn't absolutely necessary.
    202199 *
    203  * Returns: 0 if successful, else negative.  (See ERRS.H)
    204  *
    205  */
    206 
    207 short decode_gif_data(image *im, FILE *fp)
    208 
    209    {
    210    register unsigned char *sp, *bufptr;
    211    unsigned char *buf;
    212    register short code, fc, oc, bufcnt;
    213    short c, size, ret,y;
    214    ufp=fp;
    215    /* Initialize for decoding a new image...
    216     */
    217    if ((size = get_byte()) < 0)
    218       return(size);
    219    if (size < 2 || 9 < size)
    220       return(BAD_CODE_SIZE);
    221    init_exp(size);
    222 
    223    /* Initialize in case they forgot to put in a clear code.
    224     * (This shouldn't happen, but we'll try and decode it anyway...)
    225     */
    226    oc = fc = 0;
    227 
    228    /* Allocate space for the decode buffer
    229     */
    230    buf=im->scan_line(0);  y=0;
    231 /*   if ((buf = (unsigned char *)malloc(linewidth + 1)) == NULL)
    232       return(OUT_OF_MEMORY); */
    233 
    234    /* Set up the stack pointer and decode buffer pointer
    235     */
    236    sp = stack;
    237    bufptr = buf;
    238    bufcnt = im->height();
    239 
    240    /* This is the main loop.  For each code we get we pass through the
    241     * linked list of prefix codes, pushing the corresponding "character" for
    242     * each code onto the stack.  When the list reaches a single "character"
    243     * we push that on the stack too, and then start unstacking each
    244     * character for output in the correct order.  Special handling is
    245     * included for the clear code, and the whole thing ends when we get
    246     * an ending code.
    247     */
    248    while ((c = get_next_code()) != ending)
    249       {
    250 
    251       /* If we had a file error, return without completing the decode
    252        */
    253       if (c < 0)
    254      {
    255 //     free(buf);
    256      return(0);
    257      }
    258 
    259       /* If the code is a clear code, reinitialize all necessary items.
    260        */
    261       if (c == clear)
    262      {
    263      curr_size = size + 1;
    264      slot = newcodes;
    265      top_slot = 1 << curr_size;
    266 
    267      /* Continue reading codes until we get a non-clear code
    268       * (Another unlikely, but possible case...)
    269       */
    270      while ((c = get_next_code()) == clear)
    271         ;
    272 
    273      /* If we get an ending code immediately after a clear code
    274       * (Yet another unlikely case), then break out of the loop.
    275       */
    276      if (c == ending)
    277         break;
    278 
    279      /* Finally, if the code is beyond the range of already set codes,
    280       * (This one had better NOT happen...  I have no idea what will
    281       * result from this, but I doubt it will look good...) then set it
    282       * to color zero.
    283       */
    284     CONDITION(c<slot,"Error occurred while reading gif");
    285      if (c >= slot)
    286         c = 0;
    287 
    288      oc = fc = c;
    289 
    290      /* And let us not forget to put the char into the buffer... And
    291       * if, on the off chance, we were exactly one pixel from the end
    292       * of the line, we have to send the buffer to the out_line()
    293       * routine...
    294       */
    295      *bufptr++ = c;
    296      if (--bufcnt == 0)
    297         {
    298 
    299 //        if ((ret = out_line(buf, linewidth)) < 0)
    300 //           {
    301 //           free(buf);
    302 //           return(ret);
    303 //           }
    304         y++;
    305         if (y<im->height())
    306           buf=im->scan_line(y);
    307         bufptr = buf;
    308         bufcnt = im->width()-1;
    309         }
    310      }
    311       else
    312      {
    313 
    314      /* In this case, it's not a clear code or an ending code, so
    315       * it must be a code code...  So we can now decode the code into
    316       * a stack of character codes. (Clear as mud, right?)
    317       */
    318      code = c;
    319 
    320      /* Here we go again with one of those off chances...  If, on the
    321       * off chance, the code we got is beyond the range of those already
    322       * set up (Another thing which had better NOT happen...) we trick
    323       * the decoder into thinking it actually got the last code read.
    324       * (Hmmn... I'm not sure why this works...  But it does...)
    325       */
    326 
    327      if (code >= slot)
    328         {
    329         if (code > slot)
    330            ++bad_code_count;
    331         code = oc;
    332         *sp++ = fc;
    333         }
    334 
    335      /* Here we scan back along the linked list of prefixes, pushing
    336       * helpless characters (ie. suffixes) onto the stack as we do so.
    337       */
    338      while (code >= newcodes)
    339         {
    340         *sp++ = suffix[code];
    341         code = prefix[code];
    342         }
    343 
    344      /* Push the last character on the stack, and set up the new
    345       * prefix and suffix, and if the required slot number is greater
    346       * than that allowed by the current bit size, increase the bit
    347       * size.  (NOTE - If we are all full, we *don't* save the new
    348       * suffix and prefix...  I'm not certain if this is correct...
    349       * it might be more proper to overwrite the last code...
    350       */
    351      *sp++ = code;
    352      if (slot < top_slot)
    353         {
    354         suffix[slot] = fc = code;
    355         prefix[slot++] = oc;
    356         oc = c;
    357         }
    358      if (slot >= top_slot)
    359         if (curr_size < 12)
    360            {
    361            top_slot <<= 1;
    362            ++curr_size;
    363            }
    364 
    365      /* Now that we've pushed the decoded string (in reverse order)
    366       * onto the stack, lets pop it off and put it into our decode
    367       * buffer...  And when the decode buffer is full, write another
    368       * line...
    369       */
    370      while (sp > stack)
    371         {
    372         *bufptr++ = *(--sp);
    373         if (--bufcnt == 0)
    374            {
    375 /*           if ((ret = out_line(buf, linewidth)) < 0)
    376           {
    377           free(buf);
    378           return(ret);
    379           } */
    380            y++;
    381            if (y<im->height())
    382          buf=im->scan_line(y);
    383 
    384            bufptr = buf;
    385            bufcnt = im->width()-1;
    386            }
    387         }
    388      }
    389       }
    390    ret = 0;
    391    return(ret);
    392    }
    393 
     200 * Returns: 0 if successful, else negative.  (See ERRS.H) */
     201int16_t decode_gif_data(image *im, FILE *fp)
     202{
     203    register uint8_t *sp, *bufptr;
     204    uint8_t *buf;
     205    register int16_t code, fc, oc, bufcnt;
     206    int16_t c, size, y;
     207
     208    ufp = fp;
     209
     210    /* Initialize for decoding a new image... */
     211    if ((size = get_byte()) < 0)
     212        return size;
     213    if (size < 2 || 9 < size)
     214        return BAD_CODE_SIZE;
     215    init_exp(size);
     216
     217    /* Initialize in case they forgot to put in a clear code.
     218     * (This shouldn't happen, but we'll try and decode it anyway...) */
     219    oc = fc = 0;
     220
     221    /* Allocate space for the decode buffer */
     222    buf = im->scan_line(0);
     223    y = 0;
     224/*   if ((buf = (uint8_t *)malloc(linewidth + 1)) == NULL)
     225      return OUT_OF_MEMORY; */
     226
     227    /* Set up the stack pointer and decode buffer pointer */
     228    sp = stack;
     229    bufptr = buf;
     230    bufcnt = im->height();
     231
     232    /* This is the main loop.  For each code we get we pass through the
     233     * linked list of prefix codes, pushing the corresponding "character" for
     234     * each code onto the stack.  When the list reaches a single "character"
     235     * we push that on the stack too, and then start unstacking each
     236     * character for output in the correct order.  Special handling is
     237     * included for the clear code, and the whole thing ends when we get
     238     * an ending code. */
     239    while ((c = get_next_code()) != ending)
     240    {
     241        /* If we had a file error, return without completing the decode */
     242        if (c < 0)
     243        {
     244            //free(buf);
     245            return 0;
     246        }
     247
     248        /* If the code is a clear code, reinitialize all necessary items. */
     249        if (c == clear)
     250        {
     251            curr_size = size + 1;
     252            slot = newcodes;
     253            top_slot = 1 << curr_size;
     254
     255            /* Continue reading codes until we get a non-clear code
     256             * (Another unlikely, but possible case...) */
     257            while ((c = get_next_code()) == clear)
     258                ;
     259
     260            /* If we get an ending code immediately after a clear code
     261             * (Yet another unlikely case), then break out of the loop. */
     262            if (c == ending)
     263               break;
     264
     265            /* Finally, if the code is beyond the range of already set codes,
     266             * (This one had better NOT happen...  I have no idea what will
     267             * result from this, but I doubt it will look good...) then set it
     268             * to color zero. */
     269            CONDITION(c<slot,"Error occurred while reading gif");
     270            if(c >= slot)
     271                c = 0;
     272
     273            oc = fc = c;
     274
     275            /* And let us not forget to put the char into the buffer... And
     276             * if, on the off chance, we were exactly one pixel from the end
     277             * of the line, we have to send the buffer to the out_line()
     278             * routine... */
     279            *bufptr++ = c;
     280            if(--bufcnt == 0)
     281            {
     282
     283//              if ((ret = out_line(buf, linewidth)) < 0)
     284//              {
     285//                  free(buf);
     286//                  return ret;
     287//              }
     288                y++;
     289                if(y < im->height())
     290                    buf = im->scan_line(y);
     291                bufptr = buf;
     292                bufcnt = im->width() - 1;
     293            }
     294        }
     295        else
     296        {
     297            /* In this case, it's not a clear code or an ending code, so
     298             * it must be a code code...  So we can now decode the code into
     299             * a stack of character codes. (Clear as mud, right?) */
     300            code = c;
     301
     302            /* Here we go again with one of those off chances...  If, on the
     303             * off chance, the code we got is beyond the range of those already
     304             * set up (Another thing which had better NOT happen...) we trick
     305             * the decoder into thinking it actually got the last code read.
     306             * (Hmmn... I'm not sure why this works...  But it does...) */
     307            if(code >= slot)
     308            {
     309                if (code > slot)
     310                    ++bad_code_count;
     311                code = oc;
     312                *sp++ = fc;
     313            }
     314
     315            /* Here we scan back along the linked list of prefixes, pushing
     316             * helpless characters (ie. suffixes) onto the stack as we do so. */
     317            while (code >= newcodes)
     318            {
     319                *sp++ = suffix[code];
     320                code = prefix[code];
     321            }
     322
     323            /* Push the last character on the stack, and set up the new
     324             * prefix and suffix, and if the required slot number is greater
     325             * than that allowed by the current bit size, increase the bit
     326             * size.  (NOTE - If we are all full, we *don't* save the new
     327             * suffix and prefix...  I'm not certain if this is correct...
     328             * it might be more proper to overwrite the last code... */
     329            *sp++ = code;
     330            if(slot < top_slot)
     331            {
     332                suffix[slot] = fc = code;
     333                prefix[slot++] = oc;
     334                oc = c;
     335            }
     336            if(slot >= top_slot && curr_size < 12)
     337            {
     338                top_slot <<= 1;
     339                ++curr_size;
     340            }
     341
     342            /* Now that we've pushed the decoded string (in reverse order)
     343             * onto the stack, lets pop it off and put it into our decode
     344             * buffer...  And when the decode buffer is full, write another
     345             * line... */
     346            while (sp > stack)
     347            {
     348                *bufptr++ = *(--sp);
     349                if (--bufcnt == 0)
     350                {
     351/*                  if ((ret = out_line(buf, linewidth)) < 0)
     352                    {
     353                        free(buf);
     354                        return ret;
     355                    } */
     356                    y++;
     357                    if(y < im->height())
     358                        buf = im->scan_line(y);
     359       
     360                    bufptr = buf;
     361                    bufcnt = im->width() - 1;
     362                }
     363            }
     364        }
     365    }
     366
     367    return 0;
     368}
     369
  • abuse/trunk/src/imlib/filter.cpp

    r124 r128  
    8282  unsigned char *c;
    8383  CONDITION(im,"null image passed in filter::apply\n");
     84  im->lock();
    8485  for (y=im->height()-1;y>=0;y--)
    8586  {
     
    9192    }
    9293  }
     94  im->unlock();
    9395}
    9496
     
    108110  else return 0;
    109111}
    110 
    111 
    112 /*color_filter::color_filter(palette *pal, int color_bits)
    113 {
    114   unsigned char map[256],*last_start,*start;
    115   int i,last_color=0,color;
    116   compare_pal=pal;
    117   for (i=0;i,256;i++)
    118     map[i]=i;
    119 
    120   qsort(map,1,1,color_compare);
    121   colors=1<<color_bits;
    122   last_start=color_table=(unsigned char *)malloc(colors*colors*colors);
    123 
    124 
    125 
    126   last_color=map[0];
    127   last_dist=0;
    128 
    129 
    130   for (i=1;i<colors;i++)
    131   {
    132     color=map[i<<(8-color_bits)];
    133     dist=
    134 
    135     memset(c,
    136   }
    137 
    138 
    139 }*/
    140 
    141112
    142113color_filter::color_filter(palette *pal, int color_bits, void (*stat_fun)(int))
  • abuse/trunk/src/imlib/gifdecod.hpp

    r57 r128  
    1010#ifndef __GIFDECOD__
    1111#define __GIFDECOD__
     12
    1213#include "std.h"
    1314#include "image.hpp"
    1415#include <stdio.h>
    15 WORD decode_gif_data(image *im, FILE *fp);
     16int16_t decode_gif_data(image *im, FILE *fp);
     17
    1618#endif
    1719
  • abuse/trunk/src/imlib/gifread.cpp

    r124 r128  
    115115        make_block(sizeof(image));
    116116        im=new image(gif_image.w+1,gif_image.h);
     117        im->lock();
    117118        decode_gif_data(im,fp);
     119        im->unlock();
    118120        fclose(fp);
    119121          }
  • abuse/trunk/src/imlib/glread.cpp

    r124 r128  
    2121{
    2222  image *im,*sub;
    23   uint16_t length,y;
     23  int length, y;
    2424  uint8_t size,first,width,height,gsize,last;
    2525  FILE *fp;
  • abuse/trunk/src/imlib/image.hpp

    r124 r128  
    156156    {
    157157        return (int16_t)h;
     158    }
     159    int16_t pitch()
     160    {
     161        return (int16_t)w; // FIXME: for now, pitch == width
    158162    }
    159163    void scroll(int16_t x1, int16_t y1, int16_t x2, int16_t y2,
  • abuse/trunk/src/imlib/jwindow.cpp

    r124 r128  
    491491    if(_name)
    492492    {
    493 fprintf(stderr, "redrawing '%s'\n", _name);
    494493        if (right_border() >= 1)
    495494        {
     
    511510  else
    512511    {
    513 fprintf(stderr, "redrawing unknown'\n");
    514512      if (right_border() >= 1)
    515513        {
Note: See TracChangeset for help on using the changeset viewer.