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