0bb07adc9b22ade497a57250f5200c21a024e2be
[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 = (ImageRec *)malloc(sizeof(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 = (unsigned char *)malloc(image->xsize*256);
139   image->tmpR = (unsigned char *)malloc(image->xsize*256);
140   image->tmpG = (unsigned char *)malloc(image->xsize*256);
141   image->tmpB = (unsigned char *)malloc(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 = (unsigned *)malloc(x);
151       image->rowSize = (int *)malloc(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   free(image->tmp);
173   free(image->tmpR);
174   free(image->tmpG);
175   free(image->tmpB);
176   free(image);
177 }
178 /*----------------------------------------------------------------------*/
179
180 static void
181 ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
182   unsigned char *iPtr, *oPtr, pixel;
183   int count;
184
185   if ((image->type & 0xFF00) == 0x0100) {
186     fseek(image->file, image->rowStart[y+z*image->ysize], SEEK_SET);
187     fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
188       image->file);
189
190     iPtr = image->tmp;
191     oPtr = buf;
192     while (1) {
193       pixel = *iPtr++;
194       count = (int)(pixel & 0x7F);
195       if (!count) {
196         return;
197       }
198       if (pixel & 0x80) {
199         while (count--) {
200           *oPtr++ = *iPtr++;
201         }
202       } else {
203         pixel = *iPtr++;
204         while (count--) {
205           *oPtr++ = pixel;
206         }
207       }
208     }
209   } else {
210     fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
211       SEEK_SET);
212     fread(buf, 1, image->xsize, image->file);
213   }
214 }
215
216 /*----------------------------------------------------------------------*/
217 /*
218 * Fonctions publiques 
219 */
220
221 /*----------------------------------------------------------------------*/
222 void ReadScaledImage(char *file, int xsize, int ysize, char *buf, unsigned short *zsize)
223 {    
224   ImageRec *image = ImageOpen(file);
225   unsigned char *rbuf, *gbuf=NULL, *bbuf=NULL;    
226   int row, rrow, i, ri;
227   char *p = buf;
228
229   *zsize = image->zsize;
230
231   /* Allocation memoire */
232   rbuf=(unsigned char *)malloc(image->xsize * sizeof(unsigned char));
233
234   if (image->zsize > 2) {
235     gbuf = (unsigned char *) malloc (image->xsize * sizeof(unsigned char));
236     bbuf = (unsigned char *) malloc (image->xsize * sizeof(unsigned char));
237   }
238
239   /* Lecture image rang apres rang */    
240   for (row = 0; row < ysize; row++) {
241     /* rang a lire */
242     rrow = (row*image->ysize)/ysize;
243
244     if (*zsize > 2) {
245       ImageGetRow(image, rbuf, rrow, 0);
246       ImageGetRow(image, gbuf, rrow, 1);
247       ImageGetRow(image, bbuf, rrow, 2);
248     }
249     else
250       ImageGetRow(image, rbuf, rrow, 0);
251
252     /* stockage au format RGB */
253     for (i=0; i < xsize; i++) {
254       ri = (i*image->xsize)/xsize;
255       if (*zsize > 2) {
256         *p++ = rbuf[ri];
257         *p++ = gbuf[ri];
258         *p++ = bbuf[ri];
259       }
260       else {
261         *p++ = rbuf[ri];
262         *p++ = rbuf[ri];
263         *p++ = rbuf[ri];
264       }
265     }
266   }
267
268   /* delete image buffers */
269   free(rbuf);
270   if (*zsize > 2) {
271     free(gbuf);
272     free(bbuf);
273   }
274
275   ImageClose(image);    
276 }
277
278 /*----------------------------------------------------------------------*/
279 void ReadSizeImage(char *file, int *xsize, int *ysize)
280 {
281   /* Lecture image */
282   ImageRec *image = ImageOpen(file);
283
284   /* Affectation taille */
285   *xsize = image->xsize;
286   *ysize = image->ysize;
287 }
288
289 /*----------------------------------------------------------------------*/
290 void bwtorgba(unsigned char *b,unsigned char *l,int n) {
291   while(n--) {
292     l[0] = *b;
293     l[1] = *b;
294     l[2] = *b;
295     l[3] = 0xff;
296     l += 4; b++;
297   }
298 }
299
300 /*----------------------------------------------------------------------*/
301
302 void rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
303   while(n--) {
304     l[0] = r[0];
305     l[1] = g[0];
306     l[2] = b[0];
307     l[3] = 0xff;
308     l += 4; r++; g++; b++;
309   }
310 }
311
312 /*----------------------------------------------------------------------*/
313
314 void rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
315   while(n--) {
316     l[0] = r[0];
317     l[1] = g[0];
318     l[2] = b[0];
319     l[3] = a[0];
320     l += 4; r++; g++; b++; a++;
321   }
322 }
323
324 /*----------------------------------------------------------------------*/
325
326 unsigned *
327 read_texture(char *name, int *width, int *height, int *components) {
328   unsigned *base, *lptr;
329   unsigned char *rbuf, *gbuf, *bbuf, *abuf;
330   ImageRec *image;
331   int y;
332
333   image = ImageOpen(name);
334
335   if(!image)
336     return NULL;
337   (*width)=image->xsize;
338   (*height)=image->ysize;
339   (*components)=image->zsize;
340   base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
341   rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
342   gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
343   bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
344   abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
345   if(!base || !rbuf || !gbuf || !bbuf)
346     return NULL;
347   lptr = base;
348   for(y=0; y<image->ysize; y++) {
349     if(image->zsize>=4) {
350       ImageGetRow(image,rbuf,y,0);
351       ImageGetRow(image,gbuf,y,1);
352       ImageGetRow(image,bbuf,y,2);
353       ImageGetRow(image,abuf,y,3);
354       rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
355       lptr += image->xsize;
356     } else if(image->zsize==3) {
357       ImageGetRow(image,rbuf,y,0);
358       ImageGetRow(image,gbuf,y,1);
359       ImageGetRow(image,bbuf,y,2);
360       rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
361       lptr += image->xsize;
362     } else {
363       ImageGetRow(image,rbuf,y,0);
364       bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
365       lptr += image->xsize;
366     }
367   }
368   ImageClose(image);
369   free(rbuf);
370   free(gbuf);
371   free(bbuf);
372   free(abuf);
373
374   return (unsigned *) base;
375 }
376
377 /*----------------------------------------------------------------------*/