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