0023426: Tool to compare two runs of tests on the same station
[occt.git] / src / Xw / Xw_load_gif_image.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
2//
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.
7//
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.
10//
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.
17
7fd59977 18/*
19 * Created: zov : 22-Apr-1998 : Loads GIF image from file
20 *
21
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
27
28 Gets an image from a file.
29 Note, that the file must be GIF formatted.
30
31 Returns the image descriptor address if successful; or NULL if failed.
32*/
33
34#define PURIFY /*GG+STT 11/01/99
35// Avoid Free memory leak.
36*/
37
38#include <Xw_Extension.h>
39#include <fcntl.h>
40
41
42#define _ADD_PIXEL(idx) \
43{ \
44 if (y < height) *(pidata + y*width + x) = ((unsigned char)(idx)); \
45 if (++x == width) { \
46 x = 0; \
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; \
52 default: y += 2; \
53 } \
54 } \
55}
56
57/* Note,
58** Portions Copyright (c) of CISIGRAPH SOFTWARE.
59**
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
65** implied warranty.
66*/
67
68XW_EXT_IMAGEDATA *Xw_load_gif_image (void *awindow,void *aimageinfo,char *filename,int fimage,
69 XColor **ppcolors, int *pncolors)
70{
71// XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW *)awindow;
72 XW_EXT_IMAGEDATA *pimage = NULL;
73// XW_STATUS status;
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;
82 long lFileSize;
83// int i, isize, dataSize, ncolors;
84 int i, ncolors;
85static unsigned char *pchFileStream_start = NULL,
86 *pchFileStream, *ptr1, *rasterPtr = NULL;
87 int isInterlace, hasColormap;
88
89
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)
94 )
95 goto _ExitReadError;
96
97 pchFileStream = pchFileStream_start + 10;
98
99
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;
104
105#ifdef DEBUG
106 fprintf (stderr, "\r\nXw_load_gif_image: GIF contains %d colors.",
107 hasColormap? ncolors: 0);
108#endif /*DEBUG*/
109
110 pchFileStream += 2; /* Skip background byte and following zero byte */
111
112 if (ncolors > 0) { /* Allocate Color Table entries */
113
114 if (! (pcolors = (XColor*) Xw_calloc(ncolors, sizeof(XColor))))
115 goto _ExitAllocError;
116
117 for (i=0; i<ncolors; i++) { /* Fill in array of XColor's used */
118
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;
123
124 pcolors[i].flags = DoRed|DoGreen|DoBlue;
125
126 pcolors[i].pixel = i;
127 pcolors[i].pad = 0;
128 }
129 }
130
131
132#ifdef DEBUG
133 if (*pchFileStream == '!')
134 fprintf (stderr, "\r\nXw_load_gif_image: GIF contains extension blocks"
135 " (code: %x).", (int)*(pchFileStream + 1));
136 else
137 fprintf (stderr, "\r\nXw_load_gif_image: GIF has no extension blocks.");
138#endif /*DEBUG*/
139
140
141 /* Skip extension blocks if any.
142 * Format: <'!'><size><...><size><...><0>
143 */
144 while (*pchFileStream == '!') {
145
146 pchFileStream += 2; /* skip code byte followed '!' sign */
147
148 while (*pchFileStream)
149 pchFileStream += (unsigned)(1 + *(unsigned char *)pchFileStream);
150
151 pchFileStream ++;
152 }
153
154
155
156 if (*pchFileStream++ != ',') { /* must be an image descriptor */
157
158#ifdef DEB
159 fprintf (stderr, "\r\nXw_load_gif_image: Error: There's no separator"
160 " following the colormap");
161#endif /*DEB*/
162
163 goto _ExitReadError;
164 }
165
166
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;
172
173
174 byte = *pchFileStream++;
175
176 isInterlace = byte & 0x40;
177
178 if (byte & 0x80) {
179
180 fprintf (stderr, "\r\nXw_load_gif_image:"
181 " Can't read GIF image with locally defined colormap!\r\n");
182 goto _ExitReadError;
183 }
184
185
186#ifdef DEBUG
187 fprintf (stderr, "\r\nXw_load_gif_image: Dimensions: %dx%d"
188 " Interlace mode: %s",
189 width, height, isInterlace? "ON": "OFF");
190#endif /*DEBUG*/
191
192
193
194 /* Allocate the pixel buffer */
195 if (! (rasterPtr = (unsigned char *) Xw_malloc(lFileSize)))
196 goto _ExitAllocError;
197
198
199 OutCode = (unsigned *)Xw_malloc(1025 * sizeof (unsigned));
200 Prefix = (unsigned *)Xw_malloc(4096 * sizeof (unsigned));
201 Suffix = (unsigned *)Xw_malloc(4096 * sizeof (unsigned));
202
203 if (!OutCode || !Prefix || !Suffix)
204 goto _ExitAllocError;
205
206
207
208 /* Decode compressed raster data. */
209 CodeSize = *pchFileStream++;
210 ClearCode = 1 << CodeSize;
211 EOFCode = ClearCode + 1;
212 FreeCode = FirstFree = EOFCode + 1;
213
214 ++CodeSize;
215
216 InitCodeSize = CodeSize;
217 MaxCode = 1 << CodeSize;
218 ReadMask = MaxCode - 1;
219
220 ptr1 = rasterPtr;
221
222 /* Read encoded data to a continuous array pointed to by rsterPtr */
223 do {
224 byte = byte1 = *pchFileStream++;
225
226 while (byte--)
227 *ptr1++ = *pchFileStream++;
228
229 if ((long) (ptr1 - rasterPtr) > lFileSize) /* Currupt file */
230 goto _ExitReadError;
231 }
232 while (byte1);
233
234 Xw_free (pchFileStream_start); /* The file data has been already read */
235 pchFileStream_start = NULL;
236
237
238
239 if (! (pidata = (char *) Xw_malloc (width*height)))
240 goto _ExitAllocError;
241
242
243 x = y = pass = OutCount = BitOffset = ByteOffset = 0;
244
245 /* Fetch the next code (3 to 12 bits) from the raster data stream */
246 Code = rasterPtr[0] + (((unsigned) rasterPtr[1]) << 8);
247 if (CodeSize >= 8)
248 Code += ((unsigned) rasterPtr[2]) << 16;
249
250 Code >>= BitOffset & 0x7;
251 BitOffset += CodeSize;
252 Code &= ReadMask;
253
254
255 while (Code != EOFCode) {
256
257
258 if (Code == ClearCode) {
259
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];
267
268 Code = rasterPtr[ByteOffset]
269 + (((unsigned) rasterPtr[ByteOffset + 1]) << 8);
270 if (CodeSize >= 8)
271 Code += ((unsigned) rasterPtr[ByteOffset + 2]) << 16;
272
273 Code >>= BitOffset & 0x7;
274 BitOffset += CodeSize;
275 Code &= ReadMask;
276
277 CurCode = OldCode = Code;
278 FinChar = CurCode & BitMask;
279
280 _ADD_PIXEL (FinChar);
281 }
282 else {
283
284 CurCode = InCode = Code;
285
286 if (CurCode >= FreeCode) {
287
288 CurCode = OldCode;
289 OutCode[OutCount++] = FinChar;
290 }
291
292 while (CurCode > BitMask) {
293
294 if (OutCount > 1024)
295 goto _ExitReadError;
296
297 OutCode [OutCount++] = Suffix [CurCode];
298 CurCode = Prefix [CurCode];
299 }
300
301 FinChar = CurCode & BitMask;
302 OutCode [OutCount++] = FinChar;
303
304 for (i = OutCount - 1; i >= 0; --i)
305 _ADD_PIXEL (OutCode [i]);
306
307 OutCount = 0;
308 Prefix [FreeCode] = OldCode;
309 Suffix [FreeCode] = FinChar;
310 OldCode = InCode;
311 ++FreeCode;
312
313 if (FreeCode >= MaxCode) {
314
315 if (CodeSize < 12) {
316
317 ++CodeSize;
318 MaxCode <<= 1;
319 ReadMask = (1 << CodeSize) - 1;
320 }
321 }
322 }
323
324 ByteOffset = BitOffset >> 3;
325 Code = (unsigned) rasterPtr[ByteOffset];
326 Code = (unsigned) rasterPtr[ByteOffset]
327 + (((unsigned) rasterPtr[ByteOffset + 1]) << 8);
328 if (CodeSize >= 8)
329 Code += ((unsigned) rasterPtr[ByteOffset + 2]) << 16;
330
331 Code >>= (BitOffset & 0x7);
332 BitOffset += CodeSize;
333 Code &= ReadMask;
334 }
335
336
337 /* Allocate the Image structure */
338 if (! (pximage = (XImage*) Xw_malloc(sizeof(XImage))))
339 goto _ExitAllocError;
340
341 /* Allocate the Extended Image structure */
342 if(! (pimage = Xw_add_imagedata_structure (sizeof(XW_EXT_IMAGEDATA))))
343 goto _ExitError;
344
345
346 /* Initialize the input image */
347 pimage->pimageinfo = aimageinfo;
348 _IIMAGE = pximage;
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);
366
367
368 /* Return array of colors */
369 *ppcolors = pcolors;
370 *pncolors = ncolors;
371
372 if (wname) Xw_free(wname);
373
374
375#ifdef DEBUG
376 fprintf (stderr, "\r\nXw_load_gif_image: Operation completed successfully.\r\n");
377#endif /*DEBUG*/
378
379
380 /* Successfully loaded */
381
382#ifdef PURIFY
383 if (rasterPtr) Xw_free (rasterPtr);
384 if (OutCode) Xw_free (OutCode);
385 if (Prefix) Xw_free (Prefix);
386 if (Suffix) Xw_free (Suffix);
387#endif
388 return (pimage);
389
390
391
392_ExitReadError:
393
394 /*ERROR*Unable to read Image data
395 Xw_set_error(61,"Xw_load_gif_image",filename);
396 */
397 fprintf (stderr, "\r\nXw_load_gif_image: Error reading %s!", filename);
398 goto _ExitError;
399
400
401_ExitAllocError:
402 /*ERROR*Bad Image allocation
403 Xw_set_error(60,"Xw_load_gif_image",0);
404 */
405 fprintf (stderr, "\r\nXw_load_gif_image: Error: Out of memory!");
406
407
408_ExitError:
409
410#ifdef DEB
411 fprintf (stderr, "\r\nXw_load_gif_image: An error occured! Returning NULL.");
412#endif /*DEB*/
413
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);
423
424 return (NULL);
425}
426
427#undef _ADD_PIXEL