0023830: BRepExtrema_DistShapeShape does not find intersection of face with edge
[occt.git] / src / Xw / Xw_load_gif_image.cxx
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
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
68 XW_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;
85 static  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