1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
19 * Created: zov : 22-Apr-1998 : Loads GIF image from file
22 XW_EXT_IMAGEDATA* Xw_load_gif_image (awindow,aimageinfo,fimage,ppcolors,pncolors)
23 XW_EXT_WINDOW *awindow
24 XW_USERDATA *aimageinfo
25 XColor **ppcolors - address of pointer to array of used colors to return
26 int *pncolors - address of a variable to return length of the array in
28 Gets an image from a file.
29 Note, that the file must be GIF formatted.
31 Returns the image descriptor address if successful; or NULL if failed.
34 #define PURIFY /*GG+STT 11/01/99
35 // Avoid Free memory leak.
38 #include <Xw_Extension.h>
42 #define _ADD_PIXEL(idx) \
44 if (y < height) *(pidata + y*width + x) = ((unsigned char)(idx)); \
47 if (!isInterlace) ++y; \
48 else switch (pass) { \
49 case 0: y += 8; if (y >= height) ++pass, y = 4; break; \
50 case 1: y += 8; if (y >= height) ++pass, y = 2; break; \
51 case 2: y += 4; if (y >= height) ++pass, y = 1; break; \
58 ** Portions Copyright (c) of CISIGRAPH SOFTWARE.
60 ** Permission to use, copy, modify, and distribute this software and its
61 ** documentation for any purpose and without fee is hereby granted, provided
62 ** that the above copyright notice appear in all copies and that both that
63 ** copyright notice and this permission notice appear in supporting
64 ** documentation. This software is provided "as is" without express or
68 XW_EXT_IMAGEDATA *Xw_load_gif_image (void *awindow,void *aimageinfo,char *filename,int fimage,
69 XColor **ppcolors, int *pncolors)
71 // XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW *)awindow;
72 XW_EXT_IMAGEDATA *pimage = NULL;
74 XImage *pximage = NULL;
75 XColor *pcolors = NULL;
76 char *wname = NULL, *pidata = NULL;
77 unsigned char byte, byte1;
78 unsigned *OutCode=NULL, *Prefix=NULL, *Suffix=NULL,
79 BitMask, CodeSize, ClearCode, EOFCode, FreeCode, x, y, pass, width, height,
80 InitCodeSize, MaxCode, ReadMask, FirstFree, OutCount, BitOffset,
81 ByteOffset, Code, CurCode, OldCode=0, FinChar=0, InCode;
83 // int i, isize, dataSize, ncolors;
85 static unsigned char *pchFileStream_start = NULL,
86 *pchFileStream, *ptr1, *rasterPtr = NULL;
87 int isInterlace, hasColormap;
90 if (-1 == (lFileSize = lseek (fimage, 0, SEEK_END))
91 || NULL == (pchFileStream_start = (unsigned char *) Xw_malloc (lFileSize))
92 || 0 != lseek (fimage, 0, SEEK_SET)
93 || lFileSize != read (fimage, (char *)pchFileStream_start, lFileSize)
97 pchFileStream = pchFileStream_start + 10;
100 byte = *pchFileStream++; /* Color descriptor byte (M#CR0#BP) */
101 hasColormap = byte & 0x80;
102 ncolors = hasColormap ? 1<<((byte & 0x07) + 1): 1<<8;
103 BitMask = ncolors - 1;
106 fprintf (stderr, "\r\nXw_load_gif_image: GIF contains %d colors.",
107 hasColormap? ncolors: 0);
110 pchFileStream += 2; /* Skip background byte and following zero byte */
112 if (ncolors > 0) { /* Allocate Color Table entries */
114 if (! (pcolors = (XColor*) Xw_calloc(ncolors, sizeof(XColor))))
115 goto _ExitAllocError;
117 for (i=0; i<ncolors; i++) { /* Fill in array of XColor's used */
119 /* Note, that if there's no colormap specified then I use green scale */
120 pcolors[i].red = ((int)(hasColormap ? *pchFileStream++: i)) << 8; /*map to 0:ffff*/
121 pcolors[i].green = ((int)(hasColormap ? *pchFileStream++: i)) << 8;
122 pcolors[i].blue = ((int)(hasColormap ? *pchFileStream++: i)) << 8;
124 pcolors[i].flags = DoRed|DoGreen|DoBlue;
126 pcolors[i].pixel = i;
133 if (*pchFileStream == '!')
134 fprintf (stderr, "\r\nXw_load_gif_image: GIF contains extension blocks"
135 " (code: %x).", (int)*(pchFileStream + 1));
137 fprintf (stderr, "\r\nXw_load_gif_image: GIF has no extension blocks.");
141 /* Skip extension blocks if any.
142 * Format: <'!'><size><...><size><...><0>
144 while (*pchFileStream == '!') {
146 pchFileStream += 2; /* skip code byte followed '!' sign */
148 while (*pchFileStream)
149 pchFileStream += (unsigned)(1 + *(unsigned char *)pchFileStream);
156 if (*pchFileStream++ != ',') { /* must be an image descriptor */
159 fprintf (stderr, "\r\nXw_load_gif_image: Error: There's no separator"
160 " following the colormap");
167 pchFileStream += 2*2; /* Skip image left & top offsets*/
168 width = (unsigned) *pchFileStream++;
169 width += ((unsigned)*pchFileStream++) << 8;
170 height = (unsigned) *pchFileStream++;
171 height += ((unsigned)*pchFileStream++) << 8;
174 byte = *pchFileStream++;
176 isInterlace = byte & 0x40;
180 fprintf (stderr, "\r\nXw_load_gif_image:"
181 " Can't read GIF image with locally defined colormap!\r\n");
187 fprintf (stderr, "\r\nXw_load_gif_image: Dimensions: %dx%d"
188 " Interlace mode: %s",
189 width, height, isInterlace? "ON": "OFF");
194 /* Allocate the pixel buffer */
195 if (! (rasterPtr = (unsigned char *) Xw_malloc(lFileSize)))
196 goto _ExitAllocError;
199 OutCode = (unsigned *)Xw_malloc(1025 * sizeof (unsigned));
200 Prefix = (unsigned *)Xw_malloc(4096 * sizeof (unsigned));
201 Suffix = (unsigned *)Xw_malloc(4096 * sizeof (unsigned));
203 if (!OutCode || !Prefix || !Suffix)
204 goto _ExitAllocError;
208 /* Decode compressed raster data. */
209 CodeSize = *pchFileStream++;
210 ClearCode = 1 << CodeSize;
211 EOFCode = ClearCode + 1;
212 FreeCode = FirstFree = EOFCode + 1;
216 InitCodeSize = CodeSize;
217 MaxCode = 1 << CodeSize;
218 ReadMask = MaxCode - 1;
222 /* Read encoded data to a continuous array pointed to by rsterPtr */
224 byte = byte1 = *pchFileStream++;
227 *ptr1++ = *pchFileStream++;
229 if ((long) (ptr1 - rasterPtr) > lFileSize) /* Currupt file */
234 Xw_free (pchFileStream_start); /* The file data has been already read */
235 pchFileStream_start = NULL;
239 if (! (pidata = (char *) Xw_malloc (width*height)))
240 goto _ExitAllocError;
243 x = y = pass = OutCount = BitOffset = ByteOffset = 0;
245 /* Fetch the next code (3 to 12 bits) from the raster data stream */
246 Code = rasterPtr[0] + (((unsigned) rasterPtr[1]) << 8);
248 Code += ((unsigned) rasterPtr[2]) << 16;
250 Code >>= BitOffset & 0x7;
251 BitOffset += CodeSize;
255 while (Code != EOFCode) {
258 if (Code == ClearCode) {
260 /* Read the next code */
261 CodeSize = InitCodeSize;
262 MaxCode = 1 << CodeSize;
263 ReadMask = MaxCode - 1;
264 FreeCode = FirstFree;
265 ByteOffset = BitOffset >> 3;
266 Code = rasterPtr[ByteOffset];
268 Code = rasterPtr[ByteOffset]
269 + (((unsigned) rasterPtr[ByteOffset + 1]) << 8);
271 Code += ((unsigned) rasterPtr[ByteOffset + 2]) << 16;
273 Code >>= BitOffset & 0x7;
274 BitOffset += CodeSize;
277 CurCode = OldCode = Code;
278 FinChar = CurCode & BitMask;
280 _ADD_PIXEL (FinChar);
284 CurCode = InCode = Code;
286 if (CurCode >= FreeCode) {
289 OutCode[OutCount++] = FinChar;
292 while (CurCode > BitMask) {
297 OutCode [OutCount++] = Suffix [CurCode];
298 CurCode = Prefix [CurCode];
301 FinChar = CurCode & BitMask;
302 OutCode [OutCount++] = FinChar;
304 for (i = OutCount - 1; i >= 0; --i)
305 _ADD_PIXEL (OutCode [i]);
308 Prefix [FreeCode] = OldCode;
309 Suffix [FreeCode] = FinChar;
313 if (FreeCode >= MaxCode) {
319 ReadMask = (1 << CodeSize) - 1;
324 ByteOffset = BitOffset >> 3;
325 Code = (unsigned) rasterPtr[ByteOffset];
326 Code = (unsigned) rasterPtr[ByteOffset]
327 + (((unsigned) rasterPtr[ByteOffset + 1]) << 8);
329 Code += ((unsigned) rasterPtr[ByteOffset + 2]) << 16;
331 Code >>= (BitOffset & 0x7);
332 BitOffset += CodeSize;
337 /* Allocate the Image structure */
338 if (! (pximage = (XImage*) Xw_malloc(sizeof(XImage))))
339 goto _ExitAllocError;
341 /* Allocate the Extended Image structure */
342 if(! (pimage = Xw_add_imagedata_structure (sizeof(XW_EXT_IMAGEDATA))))
346 /* Initialize the input image */
347 pimage->pimageinfo = aimageinfo;
349 _IIMAGE->data = pidata;
350 _IIMAGE->width = (int) width;
351 _IIMAGE->height = (int) height;
352 _IIMAGE->xoffset = (int) 0;
353 _IIMAGE->format = (int) ZPixmap;
354 _IIMAGE->byte_order = (int) LSBFirst;
355 _IIMAGE->bitmap_unit = (int) 8;
356 _IIMAGE->bitmap_bit_order = (int) LSBFirst;
357 _IIMAGE->bitmap_pad = (int) 8;
358 _IIMAGE->depth = (int) 24;
359 _IIMAGE->bits_per_pixel = (int) 8;
360 _IIMAGE->bytes_per_line = (int) width;
361 _IIMAGE->red_mask = 0;
362 _IIMAGE->green_mask = 0;
363 _IIMAGE->blue_mask = 0;
364 _IIMAGE->obdata = NULL ;
365 _XInitImageFuncPtrs (_IIMAGE);
368 /* Return array of colors */
372 if (wname) Xw_free(wname);
376 fprintf (stderr, "\r\nXw_load_gif_image: Operation completed successfully.\r\n");
380 /* Successfully loaded */
383 if (rasterPtr) Xw_free (rasterPtr);
384 if (OutCode) Xw_free (OutCode);
385 if (Prefix) Xw_free (Prefix);
386 if (Suffix) Xw_free (Suffix);
394 /*ERROR*Unable to read Image data
395 Xw_set_error(61,"Xw_load_gif_image",filename);
397 fprintf (stderr, "\r\nXw_load_gif_image: Error reading %s!", filename);
402 /*ERROR*Bad Image allocation
403 Xw_set_error(60,"Xw_load_gif_image",0);
405 fprintf (stderr, "\r\nXw_load_gif_image: Error: Out of memory!");
411 fprintf (stderr, "\r\nXw_load_gif_image: An error occured! Returning NULL.");
414 if (pchFileStream_start) Xw_free (pchFileStream_start);
415 if (pximage) Xw_free (pximage);
416 if (rasterPtr) Xw_free (rasterPtr);
417 if (pidata) Xw_free (pidata);
418 if (pimage) Xw_free (pidata);
419 if (pcolors) Xw_free (pcolors);
420 if (OutCode) Xw_free (OutCode);
421 if (Prefix) Xw_free (Prefix);
422 if (Suffix) Xw_free (Suffix);