0023006: Improvement to debug memory leaks and insufficient memory growths.
[occt.git] / src / OpenGl / OpenGl_ImageBox.cxx
1 /*
2 * Fonction
3 * ~~~~~~~~
4 *   Gestion des images sous OpenGL
5 *
6 *
7 * Attention:
8 * ~~~~~~~~~~~
9 *  Ce package a ete teste sur SGI, OSF, SUN, HP et WNT.
10 *
11 *
12 * Historique des modifications
13 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 *   22-05-97: PCT ; creation
15 *   10-07-98: FGU ; Ajout : ReadScaledImage 
16 *                   Mise a jour des dimensions de l image
17 *    02.15.100 JR : Implicit convertion
18 */
19 /*----------------------------------------------------------------------*/
20
21 /*----------------------------------------------------------------------*/
22 /*
23 * Includes
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h> 
28 #include <string.h>
29
30 #include <OpenGl_ImageBox.hxx>
31
32 /*----------------------------------------------------------------------*/
33 /*
34 * Types definis
35 */
36
37 typedef struct _ImageRec {
38   unsigned short imagic;
39   unsigned short type;
40   unsigned short dim;
41   unsigned short xsize, ysize, zsize;
42   unsigned int min, max;
43   unsigned int wasteBytes;
44   char name[80];
45   unsigned long colorMap;
46   FILE *file;
47   unsigned char *tmp, *tmpR, *tmpG, *tmpB;
48   unsigned long rleEnd;
49   unsigned int *rowStart;
50   int *rowSize;
51 } ImageRec;
52
53 /*----------------------------------------------------------------------*/
54 /*
55 * Fonctions privees
56 */
57
58 static void
59 ConvertShort(unsigned short *array, long length) {
60   unsigned long b1, b2;
61   unsigned char *ptr;
62
63   ptr = (unsigned char *)array;
64   while (length--) {
65     b1 = *ptr++;
66     b2 = *ptr++;
67     *array++ = (unsigned short )((b1 << 8) | (b2));
68   }
69 }
70 /*----------------------------------------------------------------------*/
71
72 static void
73 ConvertLong(unsigned *array, long length) {
74   unsigned long b1, b2, b3, b4;
75   unsigned char *ptr;
76
77   ptr = (unsigned char *)array;
78   while (length--) {
79     b1 = *ptr++;
80     b2 = *ptr++;
81     b3 = *ptr++;
82     b4 = *ptr++;
83     *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
84   }
85 }
86 /*----------------------------------------------------------------------*/
87
88 static ImageRec *ImageOpen(char *fileName)
89 {
90   union {
91     int testWord;
92     char testByte[4];
93   } endianTest;
94   ImageRec *image;
95   int swapFlag;
96   int x;
97
98   endianTest.testWord = 1;
99   if (endianTest.testByte[0] == 1) {
100     swapFlag = 1;
101   } else {
102     swapFlag = 0;
103   }
104
105   image = (ImageRec *)malloc(sizeof(ImageRec));
106   if (image == NULL) {
107     fprintf(stderr, "Out of memory!\n");
108     exit(1);
109   }
110   if ((image->file = fopen(fileName, "rb")) == NULL) {
111     perror(fileName);
112     exit(1);
113   }
114
115   fread(image, 1, 12, image->file);
116
117   if (swapFlag) {
118     ConvertShort(&image->imagic, 6);
119   }
120
121   image->tmp = (unsigned char *)malloc(image->xsize*256);
122   image->tmpR = (unsigned char *)malloc(image->xsize*256);
123   image->tmpG = (unsigned char *)malloc(image->xsize*256);
124   image->tmpB = (unsigned char *)malloc(image->xsize*256);
125   if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
126     image->tmpB == NULL) {
127       fprintf(stderr, "Out of memory!\n");
128       exit(1);
129     }
130
131     if ((image->type & 0xFF00) == 0x0100) {
132       x = image->ysize * image->zsize * sizeof(unsigned);
133       image->rowStart = (unsigned *)malloc(x);
134       image->rowSize = (int *)malloc(x);
135       if (image->rowStart == NULL || image->rowSize == NULL) {
136         fprintf(stderr, "Out of memory!\n");
137         exit(1);
138       }
139       image->rleEnd = 512 + (2 * x);
140       fseek(image->file, 512, SEEK_SET);
141       fread(image->rowStart, 1, x, image->file);
142       fread(image->rowSize, 1, x, image->file);
143       if (swapFlag) {
144         ConvertLong(image->rowStart, x/sizeof(unsigned));
145         ConvertLong((unsigned *)image->rowSize, x/sizeof(int));
146       }
147     }
148     return image;
149 }
150 /*----------------------------------------------------------------------*/
151
152 static void
153 ImageClose(ImageRec *image) {
154   fclose(image->file);
155   free(image->tmp);
156   free(image->tmpR);
157   free(image->tmpG);
158   free(image->tmpB);
159   free(image);
160 }
161 /*----------------------------------------------------------------------*/
162
163 static void
164 ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
165   unsigned char *iPtr, *oPtr, pixel;
166   int count;
167
168   if ((image->type & 0xFF00) == 0x0100) {
169     fseek(image->file, image->rowStart[y+z*image->ysize], SEEK_SET);
170     fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
171       image->file);
172
173     iPtr = image->tmp;
174     oPtr = buf;
175     while (1) {
176       pixel = *iPtr++;
177       count = (int)(pixel & 0x7F);
178       if (!count) {
179         return;
180       }
181       if (pixel & 0x80) {
182         while (count--) {
183           *oPtr++ = *iPtr++;
184         }
185       } else {
186         pixel = *iPtr++;
187         while (count--) {
188           *oPtr++ = pixel;
189         }
190       }
191     }
192   } else {
193     fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
194       SEEK_SET);
195     fread(buf, 1, image->xsize, image->file);
196   }
197 }
198
199 /*----------------------------------------------------------------------*/
200 /*
201 * Fonctions publiques 
202 */
203
204 /*----------------------------------------------------------------------*/
205 void ReadScaledImage(char *file, int xsize, int ysize, char *buf, unsigned short *zsize)
206 {    
207   ImageRec *image = ImageOpen(file);
208   unsigned char *rbuf, *gbuf=NULL, *bbuf=NULL;    
209   int row, rrow, i, ri;
210   char *p = buf;
211
212   *zsize = image->zsize;
213
214   /* Allocation memoire */
215   rbuf=(unsigned char *)malloc(image->xsize * sizeof(unsigned char));
216
217   if (image->zsize > 2) {
218     gbuf = (unsigned char *) malloc (image->xsize * sizeof(unsigned char));
219     bbuf = (unsigned char *) malloc (image->xsize * sizeof(unsigned char));
220   }
221
222   /* Lecture image rang apres rang */    
223   for (row = 0; row < ysize; row++) {
224     /* rang a lire */
225     rrow = (row*image->ysize)/ysize;
226
227     if (*zsize > 2) {
228       ImageGetRow(image, rbuf, rrow, 0);
229       ImageGetRow(image, gbuf, rrow, 1);
230       ImageGetRow(image, bbuf, rrow, 2);
231     }
232     else
233       ImageGetRow(image, rbuf, rrow, 0);
234
235     /* stockage au format RGB */
236     for (i=0; i < xsize; i++) {
237       ri = (i*image->xsize)/xsize;
238       if (*zsize > 2) {
239         *p++ = rbuf[ri];
240         *p++ = gbuf[ri];
241         *p++ = bbuf[ri];
242       }
243       else {
244         *p++ = rbuf[ri];
245         *p++ = rbuf[ri];
246         *p++ = rbuf[ri];
247       }
248     }
249   }
250
251   /* delete image buffers */
252   free(rbuf);
253   if (*zsize > 2) {
254     free(gbuf);
255     free(bbuf);
256   }
257
258   ImageClose(image);    
259 }
260
261 /*----------------------------------------------------------------------*/
262 void ReadSizeImage(char *file, int *xsize, int *ysize)
263 {
264   /* Lecture image */
265   ImageRec *image = ImageOpen(file);
266
267   /* Affectation taille */
268   *xsize = image->xsize;
269   *ysize = image->ysize;
270 }
271
272 /*----------------------------------------------------------------------*/
273 void bwtorgba(unsigned char *b,unsigned char *l,int n) {
274   while(n--) {
275     l[0] = *b;
276     l[1] = *b;
277     l[2] = *b;
278     l[3] = 0xff;
279     l += 4; b++;
280   }
281 }
282
283 /*----------------------------------------------------------------------*/
284
285 void rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
286   while(n--) {
287     l[0] = r[0];
288     l[1] = g[0];
289     l[2] = b[0];
290     l[3] = 0xff;
291     l += 4; r++; g++; b++;
292   }
293 }
294
295 /*----------------------------------------------------------------------*/
296
297 void rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
298   while(n--) {
299     l[0] = r[0];
300     l[1] = g[0];
301     l[2] = b[0];
302     l[3] = a[0];
303     l += 4; r++; g++; b++; a++;
304   }
305 }
306
307 /*----------------------------------------------------------------------*/
308
309 unsigned *
310 read_texture(char *name, int *width, int *height, int *components) {
311   unsigned *base, *lptr;
312   unsigned char *rbuf, *gbuf, *bbuf, *abuf;
313   ImageRec *image;
314   int y;
315
316   image = ImageOpen(name);
317
318   if(!image)
319     return NULL;
320   (*width)=image->xsize;
321   (*height)=image->ysize;
322   (*components)=image->zsize;
323   base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
324   rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
325   gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
326   bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
327   abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
328   if(!base || !rbuf || !gbuf || !bbuf)
329     return NULL;
330   lptr = base;
331   for(y=0; y<image->ysize; y++) {
332     if(image->zsize>=4) {
333       ImageGetRow(image,rbuf,y,0);
334       ImageGetRow(image,gbuf,y,1);
335       ImageGetRow(image,bbuf,y,2);
336       ImageGetRow(image,abuf,y,3);
337       rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
338       lptr += image->xsize;
339     } else if(image->zsize==3) {
340       ImageGetRow(image,rbuf,y,0);
341       ImageGetRow(image,gbuf,y,1);
342       ImageGetRow(image,bbuf,y,2);
343       rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
344       lptr += image->xsize;
345     } else {
346       ImageGetRow(image,rbuf,y,0);
347       bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
348       lptr += image->xsize;
349     }
350   }
351   ImageClose(image);
352   free(rbuf);
353   free(gbuf);
354   free(bbuf);
355   free(abuf);
356
357   return (unsigned *) base;
358 }
359
360 /*----------------------------------------------------------------------*/