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 | |
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 | /*----------------------------------------------------------------------*/ |