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 | * 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 | |
9d35f668 |
122 | image = new ImageRec(); |
7fd59977 |
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 | |
9d35f668 |
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]; |
7fd59977 |
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); |
9d35f668 |
150 | image->rowStart = new unsigned[x]; |
151 | image->rowSize = new int[x]; |
7fd59977 |
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); |
9d35f668 |
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; |
7fd59977 |
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 */ |
9d35f668 |
234 | rbuf = new unsigned char[image->xsize]; |
7fd59977 |
235 | |
236 | if (image->zsize > 2) { |
9d35f668 |
237 | gbuf = new unsigned char[image->xsize]; |
238 | bbuf = new unsigned char[image->xsize]; |
7fd59977 |
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 */ |
9d35f668 |
271 | delete [] rbuf; |
7fd59977 |
272 | if (*zsize > 2) { |
9d35f668 |
273 | delete [] gbuf; |
274 | delete [] bbuf; |
7fd59977 |
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; |
9d35f668 |
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]; |
7fd59977 |
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); |
9d35f668 |
371 | delete [] rbuf; |
372 | delete [] gbuf; |
373 | delete [] bbuf; |
374 | delete [] abuf; |
7fd59977 |
375 | |
376 | return (unsigned *) base; |
377 | } |
378 | |
379 | /*----------------------------------------------------------------------*/ |