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