[4] | 1 | /****************************************************************************** |
---|
| 2 | * SAGE - Scalable Adaptive Graphics Environment |
---|
| 3 | * |
---|
| 4 | * Copyright (C) 2004 Electronic Visualization Laboratory, |
---|
| 5 | * University of Illinois at Chicago |
---|
| 6 | * |
---|
| 7 | * All rights reserved. |
---|
| 8 | * |
---|
| 9 | * Redistribution and use in source and binary forms, with or without |
---|
| 10 | * modification, are permitted provided that the following conditions are met: |
---|
| 11 | * |
---|
| 12 | * * Redistributions of source code must retain the above copyright |
---|
| 13 | * notice, this list of conditions and the following disclaimer. |
---|
| 14 | * * Redistributions in binary form must reproduce the above |
---|
| 15 | * copyright notice, this list of conditions and the following disclaimer |
---|
| 16 | * in the documentation and/or other materials provided with the distribution. |
---|
| 17 | * * Neither the name of the University of Illinois at Chicago nor |
---|
| 18 | * the names of its contributors may be used to endorse or promote |
---|
| 19 | * products derived from this software without specific prior written permission. |
---|
| 20 | * |
---|
| 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
---|
| 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
---|
| 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
---|
| 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
---|
| 25 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
---|
| 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
---|
| 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
---|
| 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
---|
| 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
---|
| 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
---|
| 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 32 | * |
---|
| 33 | * Direct questions, comments etc about SAGE to http://www.evl.uic.edu/cavern/forum/ |
---|
| 34 | * |
---|
| 35 | *****************************************************************************/ |
---|
| 36 | |
---|
| 37 | /*- |
---|
| 38 | * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image. |
---|
| 39 | * |
---|
| 40 | * Copyright (c) 1988 by Patrick J. Naughton |
---|
| 41 | * |
---|
| 42 | * Author: Patrick J. Naughton |
---|
| 43 | * naughton@wind.sun.com |
---|
| 44 | * |
---|
| 45 | * Permission to use, copy, modify, and distribute this software and its |
---|
| 46 | * documentation for any purpose and without fee is hereby granted, |
---|
| 47 | * provided that the above copyright notice appear in all copies and that |
---|
| 48 | * both that copyright notice and this permission notice appear in |
---|
| 49 | * supporting documentation. |
---|
| 50 | * |
---|
| 51 | * This file is provided AS IS with no warranties of any kind. The author |
---|
| 52 | * shall have no liability with respect to the infringement of copyrights, |
---|
| 53 | * trade secrets or any patents by this file or any part thereof. In no |
---|
| 54 | * event will the author be liable for any lost revenue or profits or |
---|
| 55 | * other special, indirect and consequential damages. |
---|
| 56 | * |
---|
| 57 | * Comments and additions should be sent to the author: |
---|
| 58 | * |
---|
| 59 | * Patrick J. Naughton |
---|
| 60 | * Sun Microsystems, Inc. |
---|
| 61 | * 2550 Garcia Ave, MS 14-40 |
---|
| 62 | * Mountain View, CA 94043 |
---|
| 63 | * (415) 336-1080 |
---|
| 64 | * |
---|
| 65 | * Revision History: |
---|
| 66 | * 27-Jul-88: Updated to use libpixrect to fix 386i byteswapping problems. |
---|
| 67 | * 11-Apr-88: Converted to C and changed to write Sun rasterfiles. |
---|
| 68 | * 19-Jan-88: GIFSLOW.PAS posted to comp.graphics by Jim Briebel, |
---|
| 69 | * a Turbo Pascal 4.0 program to painfully slowly display |
---|
| 70 | * GIF images on an EGA equipped IBM-PC. |
---|
| 71 | * 13-Jul-90: changed to gif2raw for use by the Geometry Supercomputer Project |
---|
| 72 | * by Cary Sandvig |
---|
| 73 | * |
---|
| 74 | * Description: |
---|
| 75 | * This program takes a Compuserve "Graphics Interchange Format" or "GIF" |
---|
| 76 | * file as input and writes a file known as a Sun rasterfile. This datafile |
---|
| 77 | * can be loaded by the NeWS "readcanvas" operator and is of the same format |
---|
| 78 | * as the files in /usr/NeWS/smi/... Under X11R2 there is a program called |
---|
| 79 | * xraster to display these files. |
---|
| 80 | * |
---|
| 81 | * Portability: |
---|
| 82 | * To make this program convert to some image format other than Sun's |
---|
| 83 | * Rasterfile format simply seach for the tag "SS:" in the source and |
---|
| 84 | * replace these simple mechanisms with the appropriate ones for the |
---|
| 85 | * other output format. I have marked all (six) Sun Specific pieces |
---|
| 86 | * of code with this comment. |
---|
| 87 | * |
---|
| 88 | * SS: compile with "cc -o gif2raw -O gif2raw.c" |
---|
| 89 | */ |
---|
| 90 | |
---|
| 91 | #include <fcntl.h> |
---|
| 92 | #include <stdio.h> |
---|
| 93 | #include <stdlib.h> |
---|
| 94 | #include <string.h> |
---|
| 95 | #include "softpic.h" |
---|
| 96 | #include "imginfo.h" |
---|
| 97 | |
---|
| 98 | typedef int boolean; |
---|
| 99 | #define True (1) |
---|
| 100 | #define False (0) |
---|
| 101 | |
---|
| 102 | #define NEXTSHORT (ptr += 2, ptr[-2] + 0x100 * ptr[-1]) |
---|
| 103 | #define NEXTBYTE (*ptr++) |
---|
| 104 | #define IMAGESEP 0x2c |
---|
| 105 | #define EXTENSION '!' |
---|
| 106 | #define TRANSPARENCY 0xF9 /* transparency extension-code */ |
---|
| 107 | #define INTERLACEMASK 0x40 |
---|
| 108 | #define COLORMAPMASK 0x80 |
---|
| 109 | |
---|
| 110 | static int BitOffset = 0, /* Bit Offset of next code */ |
---|
| 111 | XC = 0, YC = 0, /* Output X and Y coords of current pixel */ |
---|
| 112 | Pass = 0, /* Used by output routine if interlaced pic */ |
---|
| 113 | OutCount = 0, /* Decompressor output 'stack count' */ |
---|
| 114 | RWidth, RHeight, /* screen dimensions */ |
---|
| 115 | Width, Height, /* image dimensions */ |
---|
| 116 | LeftOfs, TopOfs, /* image offset */ |
---|
| 117 | BitsPerPixel, /* Bits per pixel, read from GIF header */ |
---|
| 118 | ColorMapSize, /* number of colors */ |
---|
| 119 | CodeSize, /* Code size, read from GIF header */ |
---|
| 120 | InitCodeSize, /* Starting code size, used during Clear */ |
---|
| 121 | Code, /* Value returned by ReadCode */ |
---|
| 122 | MaxCode, /* limiting value for current code size */ |
---|
| 123 | ClearCode, /* GIF clear code */ |
---|
| 124 | EOFCode, /* GIF end-of-information code */ |
---|
| 125 | CurCode, OldCode, InCode, /* Decompressor variables */ |
---|
| 126 | FirstFree, /* First free code, generated per GIF spec */ |
---|
| 127 | FreeCode, /* Decompressor, next free slot in hash table */ |
---|
| 128 | FinChar, /* Decompressor variable */ |
---|
| 129 | BitMask, /* AND mask for data size */ |
---|
| 130 | ReadMask; /* Code AND mask for current code size */ |
---|
| 131 | |
---|
| 132 | static boolean Interlace, HasColormap; |
---|
| 133 | |
---|
| 134 | static unsigned char *Image; /* The result array */ |
---|
| 135 | static unsigned char *RawGIF; /* The heap array to hold it, raw */ |
---|
| 136 | static unsigned char *Raster; /* The raster data stream, unblocked */ |
---|
| 137 | |
---|
| 138 | /* The hash table used by the decompressor */ |
---|
| 139 | static int Prefix[4096]; |
---|
| 140 | static int Suffix[4096]; |
---|
| 141 | |
---|
| 142 | /* An output array used by the decompressor */ |
---|
| 143 | static int OutCode[1025]; |
---|
| 144 | |
---|
| 145 | /* The color map, read from the GIF header */ |
---|
| 146 | static unsigned char Red[256], Green[256], Blue[256]; |
---|
| 147 | static long abgr[256]; |
---|
| 148 | |
---|
| 149 | static char *id, *id2; |
---|
| 150 | |
---|
| 151 | static char *pname; /* program name (used for error messages) */ |
---|
| 152 | |
---|
| 153 | static int ReadCode(); |
---|
| 154 | static void AddToPixel(char Index); |
---|
| 155 | |
---|
| 156 | static void error( char *s1, char *s2 ) |
---|
| 157 | { |
---|
| 158 | fprintf(stderr, s1, pname, s2); |
---|
| 159 | exit(1); |
---|
| 160 | } |
---|
| 161 | |
---|
| 162 | |
---|
| 163 | static void gif_init() |
---|
| 164 | { |
---|
| 165 | BitOffset = 0; |
---|
| 166 | XC = 0; |
---|
| 167 | YC = 0; |
---|
| 168 | Pass = 0; |
---|
| 169 | OutCount = 0; |
---|
| 170 | id = "GIF87a"; |
---|
| 171 | id2 = "GIF89a"; |
---|
| 172 | } |
---|
| 173 | |
---|
| 174 | IMG *gifmakedisp( char *inname ) |
---|
| 175 | { |
---|
| 176 | FILE *fpin; |
---|
| 177 | int filesize; |
---|
| 178 | register unsigned char ch, ch1; |
---|
| 179 | register unsigned char *ptr, *ptr1; |
---|
| 180 | IMG *out; |
---|
| 181 | int transindex = -1; |
---|
| 182 | int i, j; |
---|
| 183 | |
---|
| 184 | gif_init(); |
---|
| 185 | setbuf(stderr, NULL); |
---|
| 186 | |
---|
| 187 | fpin = fopen(inname, "rb"); |
---|
| 188 | /* find the size of the file */ |
---|
| 189 | |
---|
| 190 | fseek(fpin, 0L, 2); |
---|
| 191 | filesize = ftell(fpin); |
---|
| 192 | fseek(fpin, 0L, 0); |
---|
| 193 | |
---|
| 194 | if (!(ptr = RawGIF = (unsigned char *) malloc(filesize))) |
---|
| 195 | error("%s: not enough memory to read gif file.\n", NULL); |
---|
| 196 | |
---|
| 197 | if (!(Raster = (unsigned char *) malloc(filesize))) |
---|
| 198 | error("%s: not enough memory to read gif file.\n", NULL); |
---|
| 199 | |
---|
| 200 | fread(ptr, filesize, 1, fpin); |
---|
| 201 | |
---|
| 202 | if (memcmp(ptr, id, 6) && memcmp(ptr, id2, 6)) |
---|
| 203 | error("%s: %s is not a GIF file.\n", inname); |
---|
| 204 | ptr += 6; |
---|
| 205 | |
---|
| 206 | /* Get variables from the GIF screen descriptor */ |
---|
| 207 | |
---|
| 208 | RWidth = NEXTSHORT; /* screen dimensions... not used. */ |
---|
| 209 | RHeight = NEXTSHORT; |
---|
| 210 | |
---|
| 211 | ch = NEXTBYTE; |
---|
| 212 | HasColormap = ((ch & COLORMAPMASK) ? True : False); |
---|
| 213 | |
---|
| 214 | BitsPerPixel = (ch & 7) + 1; |
---|
| 215 | ColorMapSize = 1 << BitsPerPixel; |
---|
| 216 | BitMask = ColorMapSize - 1; |
---|
| 217 | |
---|
| 218 | ch = NEXTBYTE; /* background color... not used. */ |
---|
| 219 | |
---|
| 220 | (void) NEXTBYTE; /* what's this? */ |
---|
| 221 | |
---|
| 222 | /* Read in global colormap. */ |
---|
| 223 | |
---|
| 224 | if (HasColormap) { |
---|
| 225 | /* |
---|
| 226 | fprintf(stderr, "%s is %d bits per pixel, (%d colors).\n", |
---|
| 227 | inname, BitsPerPixel, ColorMapSize); |
---|
| 228 | */ |
---|
| 229 | for (i = 0; i < ColorMapSize; i++) { |
---|
| 230 | Red[i] = NEXTBYTE; |
---|
| 231 | Green[i] = NEXTBYTE; |
---|
| 232 | Blue[i] = NEXTBYTE; |
---|
| 233 | abgr[i] = 0xFF000000 | (Blue[i]<<16) | (Green[i]<<8) | Red[i]; |
---|
| 234 | } |
---|
| 235 | |
---|
| 236 | } |
---|
| 237 | else error("gifdisp: %s does not have a colormap.\n", inname); |
---|
| 238 | |
---|
| 239 | |
---|
| 240 | /* Skip any GIF89 extensions */ |
---|
| 241 | while((i = NEXTBYTE) == EXTENSION) { |
---|
| 242 | int extno = NEXTBYTE & 0xFF; |
---|
| 243 | int len; |
---|
| 244 | unsigned char block[256]; |
---|
| 245 | |
---|
| 246 | /* Skip <lengthbyte><data> segments until we see lengthbyte==0. */ |
---|
| 247 | while((len = NEXTBYTE) != 0) { |
---|
| 248 | for(i = 0; i < len; i++) |
---|
| 249 | block[i] = NEXTBYTE; |
---|
| 250 | } |
---|
| 251 | switch(extno) { |
---|
| 252 | case 0xF9: /* Transparency */ |
---|
| 253 | if(block[0] & 0x01) { |
---|
| 254 | transindex = block[3]; |
---|
| 255 | if(transindex >= 0 && transindex < ColorMapSize) |
---|
| 256 | abgr[transindex] &= ~0xFF000000; |
---|
| 257 | } |
---|
| 258 | break; |
---|
| 259 | } |
---|
| 260 | } |
---|
| 261 | |
---|
| 262 | /* Check for image separator */ |
---|
| 263 | if (i != IMAGESEP) |
---|
| 264 | fprintf(stderr, "gifdisp: %s is a corrupt GIF file.\n", inname); |
---|
| 265 | |
---|
| 266 | /* Now read in values from the image descriptor */ |
---|
| 267 | |
---|
| 268 | LeftOfs = NEXTSHORT; |
---|
| 269 | TopOfs = NEXTSHORT; |
---|
| 270 | Width = NEXTSHORT; |
---|
| 271 | Height = NEXTSHORT; |
---|
| 272 | Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False); |
---|
| 273 | |
---|
| 274 | /* |
---|
| 275 | fprintf(stderr, "Reading a %d by %d %sinterlaced image...", |
---|
| 276 | Width, Height, (Interlace) ? "" : "non-"); |
---|
| 277 | */ |
---|
| 278 | |
---|
| 279 | |
---|
| 280 | /* Note that I ignore the possible existence of a local color map. |
---|
| 281 | * I'm told there aren't many files around that use them, and the spec |
---|
| 282 | * says it's defined for future use. This could lead to an error |
---|
| 283 | * reading some files. |
---|
| 284 | */ |
---|
| 285 | |
---|
| 286 | /* Start reading the raster data. First we get the intial code size |
---|
| 287 | * and compute decompressor constant values, based on this code size. |
---|
| 288 | */ |
---|
| 289 | |
---|
| 290 | CodeSize = NEXTBYTE; |
---|
| 291 | ClearCode = (1 << CodeSize); |
---|
| 292 | EOFCode = ClearCode + 1; |
---|
| 293 | FreeCode = FirstFree = ClearCode + 2; |
---|
| 294 | |
---|
| 295 | /* The GIF spec has it that the code size is the code size used to |
---|
| 296 | * compute the above values is the code size given in the file, but the |
---|
| 297 | * code size used in compression/decompression is the code size given in |
---|
| 298 | * the file plus one. (thus the ++). |
---|
| 299 | */ |
---|
| 300 | |
---|
| 301 | CodeSize++; |
---|
| 302 | InitCodeSize = CodeSize; |
---|
| 303 | MaxCode = (1 << CodeSize); |
---|
| 304 | ReadMask = MaxCode - 1; |
---|
| 305 | |
---|
| 306 | /* Read the raster data. Here we just transpose it from the GIF array |
---|
| 307 | * to the Raster array, turning it from a series of blocks into one long |
---|
| 308 | * data stream, which makes life much easier for ReadCode(). |
---|
| 309 | */ |
---|
| 310 | |
---|
| 311 | ptr1 = Raster; |
---|
| 312 | do { |
---|
| 313 | ch = ch1 = NEXTBYTE; |
---|
| 314 | while (ch--) *ptr1++ = NEXTBYTE; |
---|
| 315 | } while(ch1); |
---|
| 316 | |
---|
| 317 | free(RawGIF); /* We're done with the raw data now... */ |
---|
| 318 | |
---|
| 319 | /* |
---|
| 320 | fprintf(stderr, "done.\n"); |
---|
| 321 | fprintf(stderr, "Decompressing..."); |
---|
| 322 | */ |
---|
| 323 | |
---|
| 324 | Image = (unsigned char *)calloc((Width*Height), sizeof(char)); |
---|
| 325 | |
---|
| 326 | |
---|
| 327 | /* Decompress the file, continuing until you see the GIF EOF code. |
---|
| 328 | * One obvious enhancement is to add checking for corrupt files here. |
---|
| 329 | */ |
---|
| 330 | |
---|
| 331 | Code = ReadCode(); |
---|
| 332 | while (Code != EOFCode) { |
---|
| 333 | |
---|
| 334 | /* Clear code sets everything back to its initial value, then reads the |
---|
| 335 | * immediately subsequent code as uncompressed data. |
---|
| 336 | */ |
---|
| 337 | |
---|
| 338 | if (Code == ClearCode) { |
---|
| 339 | CodeSize = InitCodeSize; |
---|
| 340 | MaxCode = (1 << CodeSize); |
---|
| 341 | ReadMask = MaxCode - 1; |
---|
| 342 | FreeCode = FirstFree; |
---|
| 343 | CurCode = OldCode = Code = ReadCode(); |
---|
| 344 | FinChar = CurCode & BitMask; |
---|
| 345 | AddToPixel(FinChar); |
---|
| 346 | } |
---|
| 347 | else { |
---|
| 348 | |
---|
| 349 | /* If not a clear code, then must be data: save same as CurCode and InCode */ |
---|
| 350 | |
---|
| 351 | CurCode = InCode = Code; |
---|
| 352 | |
---|
| 353 | /* If greater or equal to FreeCode, not in the hash table yet; |
---|
| 354 | * repeat the last character decoded |
---|
| 355 | */ |
---|
| 356 | |
---|
| 357 | if (CurCode >= FreeCode) { |
---|
| 358 | CurCode = OldCode; |
---|
| 359 | OutCode[OutCount++] = FinChar; |
---|
| 360 | } |
---|
| 361 | |
---|
| 362 | /* Unless this code is raw data, pursue the chain pointed to by CurCode |
---|
| 363 | * through the hash table to its end; each code in the chain puts its |
---|
| 364 | * associated output code on the output queue. |
---|
| 365 | */ |
---|
| 366 | |
---|
| 367 | while (CurCode > BitMask) { |
---|
| 368 | OutCode[OutCount++] = Suffix[CurCode]; |
---|
| 369 | CurCode = Prefix[CurCode]; |
---|
| 370 | } |
---|
| 371 | |
---|
| 372 | /* The last code in the chain is treated as raw data. */ |
---|
| 373 | |
---|
| 374 | FinChar = CurCode & BitMask; |
---|
| 375 | OutCode[OutCount++] = FinChar; |
---|
| 376 | |
---|
| 377 | /* Now we put the data out to the Output routine. |
---|
| 378 | * It's been stacked LIFO, so deal with it that way... |
---|
| 379 | */ |
---|
| 380 | |
---|
| 381 | for (i = OutCount - 1; i >= 0; i--) |
---|
| 382 | AddToPixel(OutCode[i]); |
---|
| 383 | OutCount = 0; |
---|
| 384 | |
---|
| 385 | /* Build the hash table on-the-fly. No table is stored in the file. */ |
---|
| 386 | |
---|
| 387 | Prefix[FreeCode] = OldCode; |
---|
| 388 | Suffix[FreeCode] = FinChar; |
---|
| 389 | OldCode = InCode; |
---|
| 390 | |
---|
| 391 | /* Point to the next slot in the table. If we exceed the current |
---|
| 392 | * MaxCode value, increment the code size unless it's already 12. If it |
---|
| 393 | * is, do nothing: the next code decompressed better be CLEAR |
---|
| 394 | */ |
---|
| 395 | |
---|
| 396 | FreeCode++; |
---|
| 397 | if (FreeCode >= MaxCode) { |
---|
| 398 | if (CodeSize < 12) { |
---|
| 399 | CodeSize++; |
---|
| 400 | MaxCode *= 2; |
---|
| 401 | ReadMask = (1 << CodeSize) - 1; |
---|
| 402 | } |
---|
| 403 | } |
---|
| 404 | } |
---|
| 405 | Code = ReadCode(); |
---|
| 406 | } |
---|
| 407 | |
---|
| 408 | free(Raster); |
---|
| 409 | |
---|
| 410 | /* |
---|
| 411 | fprintf(stderr, "done.\n"); |
---|
| 412 | |
---|
| 413 | fprintf(stderr, "outputting image.\n"); |
---|
| 414 | */ |
---|
| 415 | |
---|
| 416 | out = (IMG *)malloc(sizeof(IMG)); |
---|
| 417 | out->type = IT_LONG; |
---|
| 418 | out->rowbytes = Width * sizeof(long); |
---|
| 419 | out->xsize = Width; |
---|
| 420 | out->ysize = Height; |
---|
| 421 | out->data = (unsigned char *)malloc(4*(Width*Height)*sizeof(char)); |
---|
| 422 | |
---|
| 423 | for(j = 0; j<Height; j++) |
---|
| 424 | for (i=0; i<Width; i++) { |
---|
| 425 | *(long *)&out->data[4*(((Height - j - 1)*Width)+i)] = |
---|
| 426 | abgr[Image[j*Width + i]]; |
---|
| 427 | } |
---|
| 428 | |
---|
| 429 | free(Image); |
---|
| 430 | fclose(fpin); |
---|
| 431 | return (out); |
---|
| 432 | |
---|
| 433 | /* |
---|
| 434 | fprintf(stderr, "done.\n"); |
---|
| 435 | */ |
---|
| 436 | } |
---|
| 437 | |
---|
| 438 | |
---|
| 439 | /* Fetch the next code from the raster data stream. The codes can be |
---|
| 440 | * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to |
---|
| 441 | * maintain our location in the Raster array as a BIT Offset. We compute |
---|
| 442 | * the byte Offset into the raster array by dividing this by 8, pick up |
---|
| 443 | * three bytes, compute the bit Offset into our 24-bit chunk, shift to |
---|
| 444 | * bring the desired code to the bottom, then mask it off and return it. |
---|
| 445 | */ |
---|
| 446 | static int ReadCode() |
---|
| 447 | { |
---|
| 448 | int RawCode, ByteOffset; |
---|
| 449 | |
---|
| 450 | ByteOffset = BitOffset / 8; |
---|
| 451 | RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]); |
---|
| 452 | if (CodeSize >= 8) |
---|
| 453 | RawCode += (0x10000 * Raster[ByteOffset + 2]); |
---|
| 454 | RawCode >>= (BitOffset % 8); |
---|
| 455 | BitOffset += CodeSize; |
---|
| 456 | return(RawCode & ReadMask); |
---|
| 457 | } |
---|
| 458 | |
---|
| 459 | static void AddToPixel(char Index) |
---|
| 460 | { |
---|
| 461 | if((unsigned int)XC >= Width || (unsigned int)YC >= Height) { |
---|
| 462 | fprintf(stderr, "[BP] "); |
---|
| 463 | } else { |
---|
| 464 | *(Image + YC * Width + XC) = Index; |
---|
| 465 | } |
---|
| 466 | |
---|
| 467 | /* Update the X-coordinate, and if it overflows, update the Y-coordinate */ |
---|
| 468 | |
---|
| 469 | if (++XC == Width) { |
---|
| 470 | |
---|
| 471 | /* If a non-interlaced picture, just increment YC to the next scan line. |
---|
| 472 | * If it's interlaced, deal with the interlace as described in the GIF |
---|
| 473 | * spec. Put the decoded scan line out to the screen if we haven't gone |
---|
| 474 | * past the bottom of it |
---|
| 475 | */ |
---|
| 476 | |
---|
| 477 | XC = 0; |
---|
| 478 | if (!Interlace) YC++; |
---|
| 479 | else { |
---|
| 480 | switch (Pass) { |
---|
| 481 | case 0: |
---|
| 482 | YC += 8; |
---|
| 483 | if (YC >= Height) { |
---|
| 484 | Pass++; |
---|
| 485 | YC = 4; |
---|
| 486 | } |
---|
| 487 | break; |
---|
| 488 | case 1: |
---|
| 489 | YC += 8; |
---|
| 490 | if (YC >= Height) { |
---|
| 491 | Pass++; |
---|
| 492 | YC = 2; |
---|
| 493 | } |
---|
| 494 | break; |
---|
| 495 | case 2: |
---|
| 496 | YC += 4; |
---|
| 497 | if (YC >= Height) { |
---|
| 498 | Pass++; |
---|
| 499 | YC = 1; |
---|
| 500 | } |
---|
| 501 | break; |
---|
| 502 | case 3: |
---|
| 503 | YC += 2; |
---|
| 504 | if(YC >= Height) { |
---|
| 505 | fprintf(stderr, "[BG] "); |
---|
| 506 | YC = Height-1; /* eh?? */ |
---|
| 507 | } |
---|
| 508 | break; |
---|
| 509 | default: |
---|
| 510 | break; |
---|
| 511 | } |
---|
| 512 | } |
---|
| 513 | } |
---|
| 514 | } |
---|