GIFDECOD.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define MODULE_GIFDECOD
00025
00026
00027
00028
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <math.h>
00032
00033 #ifndef TRUE
00034 #define TRUE 1
00035 #endif
00036
00037 #ifndef FALSE
00038 #define FALSE 0
00039 #endif
00040
00041 typedef struct Colour_Struct COLOUR;
00042 typedef struct Colour_Map_Entry COLOUR_MAP_ENTRY;
00043 typedef struct Colour_Map_Struct COLOUR_MAP;
00044 typedef struct Image_Struct IMAGE;
00045
00046 struct Colour_Struct
00047 {
00048 double Red, Green, Blue, Alpha;
00049 };
00050
00051
00052 struct Colour_Map_Entry
00053 {
00054 double start, end;
00055 COLOUR Start_Colour, End_Colour;
00056 };
00057
00058
00059 struct Colour_Map_Struct
00060 {
00061 long Number_Of_Entries;
00062 COLOUR_MAP_ENTRY *Colour_Map_Entries;
00063 };
00064
00065
00066 struct Image_Struct
00067 {
00068 double width, height;
00069 long iwidth, iheight;
00070 unsigned char *red, *green, *blue;
00071 };
00072
00073
00074 typedef struct {
00075 unsigned short Red, Green, Blue;
00076 } IMAGE_COLOUR;
00077
00078 #define LOCAL static
00079 #define IMPORT extern
00080
00081 #define FAST register
00082
00083 typedef short WORD;
00084 typedef unsigned short UWORD;
00085 typedef char TEXT;
00086 typedef unsigned char UTINY;
00087 typedef long LONG;
00088 typedef unsigned long ULONG;
00089 typedef long INT;
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 #define OUT_OF_MEMORY -10
00100 #define BAD_CODE_SIZE -20
00101 #define WRITE_ERROR -2
00102 #define OPEN_ERROR -3
00103 #define CREATE_ERROR -4
00104
00105
00106
00107 #ifdef _SUNSTYLE
00108 static short init_exp ();
00109 static short get_next_code();
00110 short GIF_decoder();
00111 IMPORT long get_byte();
00112 IMPORT long out_line();
00113 #else
00114 static short init_exp (short size);
00115 static short get_next_code (void);
00116 short GIF_decoder(short linewidth);
00117 IMPORT long get_byte(void);
00118 IMPORT long out_line(unsigned char *pixels, long linelen);
00119 #endif
00120
00121
00122
00123
00124
00125
00126
00127
00128 static INT bad_code_count;
00129
00130 #define MAX_CODES 4095
00131
00132
00133 LOCAL WORD curr_size;
00134 LOCAL WORD clear;
00135 LOCAL WORD ending;
00136 LOCAL WORD newcodes;
00137 LOCAL WORD top_slot;
00138 LOCAL WORD slot;
00139
00140
00141
00142
00143 LOCAL WORD navail_bytes = 0;
00144 LOCAL WORD nbits_left = 0;
00145 LOCAL UTINY b1;
00146 LOCAL UTINY byte_buff[257];
00147 LOCAL UTINY *pbytes;
00148
00149 LOCAL LONG code_mask[13] = {
00150 0,
00151 0x0001, 0x0003,
00152 0x0007, 0x000F,
00153 0x001F, 0x003F,
00154 0x007F, 0x00FF,
00155 0x01FF, 0x03FF,
00156 0x07FF, 0x0FFF
00157 };
00158
00159 #ifdef _SUNSTYLE
00160 LOCAL WORD init_exp(size) WORD size; {
00161 #else
00162 LOCAL WORD init_exp(WORD size){
00163 #endif
00164 curr_size = size + 1;
00165 top_slot = 1 << curr_size;
00166 clear = 1 << size;
00167 ending = clear + 1;
00168 slot = newcodes = ending + 1;
00169 navail_bytes = nbits_left = 0;
00170 return(0);
00171 }
00172
00173
00174
00175
00176
00177 #ifdef _SUNSTYLE
00178 LOCAL WORD get_next_code(){
00179 #else
00180 LOCAL WORD get_next_code(void){
00181 #endif
00182 WORD i, x;
00183 ULONG ret;
00184
00185 if (nbits_left == 0)
00186 {
00187 if (navail_bytes <= 0)
00188 {
00189
00190
00191
00192 pbytes = byte_buff;
00193 if ((navail_bytes = get_byte()) < 0)
00194 return(navail_bytes);
00195 else if (navail_bytes)
00196 {
00197 for (i = 0; i < navail_bytes; ++i)
00198 {
00199 if ((x = get_byte()) < 0)
00200 return(x);
00201 byte_buff[i] = x;
00202 }
00203 }
00204 }
00205 b1 = *pbytes++;
00206 nbits_left = 8;
00207 --navail_bytes;
00208 }
00209
00210 ret = b1 >> (8 - nbits_left);
00211 while (curr_size > nbits_left)
00212 {
00213 if (navail_bytes <= 0)
00214 {
00215
00216
00217
00218 pbytes = byte_buff;
00219 if ((navail_bytes = get_byte()) < 0)
00220 return(navail_bytes);
00221 else if (navail_bytes)
00222 {
00223 for (i = 0; i < navail_bytes; ++i)
00224 {
00225 if ((x = get_byte()) < 0)
00226 return(x);
00227 byte_buff[i] = x;
00228 }
00229 }
00230 }
00231 b1 = *pbytes++;
00232 ret |= b1 << nbits_left;
00233 nbits_left += 8;
00234 --navail_bytes;
00235 }
00236 nbits_left -= curr_size;
00237 ret &= code_mask[curr_size];
00238 return((WORD)(ret));
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 LOCAL UTINY dstack[MAX_CODES + 1];
00258 LOCAL UTINY suffix[MAX_CODES + 1];
00259 LOCAL UWORD prefix[MAX_CODES + 1];
00260 extern UTINY *decoderline;
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 #ifdef _SUNSTYLE
00282 WORD GIF_decoder(linewidth) WORD linewidth; {
00283 #else
00284 WORD GIF_decoder(WORD linewidth){
00285 #endif
00286 FAST UTINY *sp, *bufptr;
00287 UTINY *buf;
00288 FAST WORD code, fc, oc, bufcnt;
00289 WORD c, size, ret;
00290
00291
00292
00293 if ((size = get_byte()) < 0)
00294 return(size);
00295 if (size < 2 || 9 < size)
00296 return(BAD_CODE_SIZE);
00297 init_exp(size);
00298
00299
00300
00301
00302 oc = fc = 0;
00303
00304 buf = decoderline;
00305
00306
00307
00308 sp = dstack;
00309 bufptr = buf;
00310 bufcnt = linewidth;
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 while ((c = get_next_code()) != ending)
00321 {
00322
00323
00324
00325 if (c < 0)
00326 return(0);
00327
00328
00329
00330 if (c == clear)
00331 {
00332 curr_size = size + 1;
00333 slot = newcodes;
00334 top_slot = 1 << curr_size;
00335
00336
00337
00338
00339 while ((c = get_next_code()) == clear)
00340 ;
00341
00342
00343
00344
00345 if (c == ending)
00346 break;
00347
00348
00349
00350
00351
00352
00353 if (c >= slot)
00354 c = 0;
00355
00356 oc = fc = c;
00357
00358
00359
00360
00361
00362
00363 *bufptr++ = c;
00364 if (--bufcnt == 0)
00365 {
00366 if ((ret = out_line(buf, linewidth)) < 0)
00367 return(ret);
00368 bufptr = buf;
00369 bufcnt = linewidth;
00370 }
00371 }
00372 else
00373 {
00374
00375
00376
00377
00378
00379 code = c;
00380
00381
00382
00383
00384
00385
00386
00387 if (code >= slot)
00388 {
00389 if (code > slot)
00390 ++bad_code_count;
00391 code = oc;
00392 *sp++ = fc;
00393 }
00394
00395
00396
00397
00398 while (code >= newcodes)
00399 {
00400 *sp++ = suffix[code];
00401 code = prefix[code];
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411 *sp++ = code;
00412 if (slot < top_slot)
00413 {
00414 suffix[slot] = fc = code;
00415 prefix[slot++] = oc;
00416 oc = c;
00417 }
00418 if (slot >= top_slot)
00419 if (curr_size < 12)
00420 {
00421 top_slot <<= 1;
00422 ++curr_size;
00423 }
00424
00425
00426
00427
00428
00429
00430 while (sp > dstack)
00431 {
00432 *bufptr++ = *(--sp);
00433 if (--bufcnt == 0)
00434 {
00435 if ((ret = out_line(buf, linewidth)) < 0)
00436 return(ret);
00437 bufptr = buf;
00438 bufcnt = linewidth;
00439 }
00440 }
00441 }
00442 }
00443 ret = 0;
00444 if (bufcnt != linewidth)
00445 ret = out_line(buf, (linewidth - bufcnt));
00446 return(ret);
00447 }
00448