~ubuntu-branches/ubuntu/jaunty/mesa/jaunty

« back to all changes in this revision

Viewing changes to progs/osdemos/readtex.c

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2009-04-03 12:42:06 UTC
  • mfrom: (1.2.16 upstream) (3.1.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20090403124206-0oo9dl0tcmd0qr38
Tags: 7.4-0ubuntu1
* New upstream release, merge from debian-experimental
  (LP: #330476, #347171, #349127)
* Drop 103_rs600_support.patch, included in this version.
* Drop 104_swrast_fbconfigs.patch, included in this version.
* Add 103_bump_965_texture_limit.diff. (LP: #146298)
* Add 104_fix_dri2_ext_tfp.diff. (LP: #324854)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* readtex.c */
2
 
 
3
 
/*
4
 
 * Read an SGI .rgb image file and generate a mipmap texture set.
5
 
 * Much of this code was borrowed from SGI's tk OpenGL toolkit.
6
 
 */
7
 
 
8
 
 
9
 
 
10
 
#include <GL/gl.h>
11
 
#include <GL/glu.h>
12
 
#include <stdio.h>
13
 
#include <stdlib.h> 
14
 
#include <string.h>
15
 
#include "readtex.h"
16
 
 
17
 
 
18
 
#ifndef SEEK_SET
19
 
#  define SEEK_SET 0
20
 
#endif
21
 
 
22
 
 
23
 
/*
24
 
** RGB Image Structure
25
 
*/
26
 
 
27
 
typedef struct _TK_RGBImageRec {
28
 
   GLint sizeX, sizeY;
29
 
   GLint components;
30
 
   unsigned char *data;
31
 
} TK_RGBImageRec;
32
 
 
33
 
 
34
 
 
35
 
/******************************************************************************/
36
 
 
37
 
typedef struct _rawImageRec {
38
 
    unsigned short imagic;
39
 
    unsigned short type;
40
 
    unsigned short dim;
41
 
    unsigned short sizeX, sizeY, sizeZ;
42
 
    unsigned long min, max;
43
 
    unsigned long wasteBytes;
44
 
    char name[80];
45
 
    unsigned long colorMap;
46
 
    FILE *file;
47
 
    unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
48
 
    unsigned long rleEnd;
49
 
    GLuint *rowStart;
50
 
    GLint *rowSize;
51
 
} rawImageRec;
52
 
 
53
 
/******************************************************************************/
54
 
 
55
 
static void ConvertShort(unsigned short *array, long length)
56
 
{
57
 
   unsigned long b1, b2;
58
 
   unsigned char *ptr;
59
 
 
60
 
   ptr = (unsigned char *)array;
61
 
   while (length--) {
62
 
      b1 = *ptr++;
63
 
      b2 = *ptr++;
64
 
      *array++ = (unsigned short) ((b1 << 8) | (b2));
65
 
   }
66
 
}
67
 
 
68
 
static void ConvertLong(GLuint *array, long length)
69
 
{
70
 
   unsigned long b1, b2, b3, b4;
71
 
   unsigned char *ptr;
72
 
 
73
 
   ptr = (unsigned char *)array;
74
 
   while (length--) {
75
 
      b1 = *ptr++;
76
 
      b2 = *ptr++;
77
 
      b3 = *ptr++;
78
 
      b4 = *ptr++;
79
 
      *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
80
 
   }
81
 
}
82
 
 
83
 
static rawImageRec *RawImageOpen(const char *fileName)
84
 
{
85
 
   union {
86
 
      int testWord;
87
 
      char testByte[4];
88
 
   } endianTest;
89
 
   rawImageRec *raw;
90
 
   GLenum swapFlag;
91
 
   int x;
92
 
 
93
 
   endianTest.testWord = 1;
94
 
   if (endianTest.testByte[0] == 1) {
95
 
      swapFlag = GL_TRUE;
96
 
   } else {
97
 
      swapFlag = GL_FALSE;
98
 
   }
99
 
 
100
 
   raw = (rawImageRec *)calloc(1, sizeof(rawImageRec));
101
 
   if (raw == NULL) {
102
 
      fprintf(stderr, "Out of memory!\n");
103
 
      return NULL;
104
 
   }
105
 
   if ((raw->file = fopen(fileName, "rb")) == NULL) {
106
 
      perror(fileName);
107
 
      return NULL;
108
 
   }
109
 
 
110
 
   fread(raw, 1, 12, raw->file);
111
 
 
112
 
   if (swapFlag) {
113
 
      ConvertShort(&raw->imagic, 6);
114
 
   }
115
 
 
116
 
   raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
117
 
   raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
118
 
   raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
119
 
   raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
120
 
   if (raw->sizeZ==4) {
121
 
      raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
122
 
   }
123
 
   if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
124
 
       raw->tmpB == NULL) {
125
 
      fprintf(stderr, "Out of memory!\n");
126
 
      return NULL;
127
 
   }
128
 
 
129
 
   if ((raw->type & 0xFF00) == 0x0100) {
130
 
      x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
131
 
      raw->rowStart = (GLuint *)malloc(x);
132
 
      raw->rowSize = (GLint *)malloc(x);
133
 
      if (raw->rowStart == NULL || raw->rowSize == NULL) {
134
 
         fprintf(stderr, "Out of memory!\n");
135
 
         return NULL;
136
 
      }
137
 
      raw->rleEnd = 512 + (2 * x);
138
 
      fseek(raw->file, 512, SEEK_SET);
139
 
      fread(raw->rowStart, 1, x, raw->file);
140
 
      fread(raw->rowSize, 1, x, raw->file);
141
 
      if (swapFlag) {
142
 
         ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
143
 
         ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
144
 
      }
145
 
   }
146
 
   return raw;
147
 
}
148
 
 
149
 
static void RawImageClose(rawImageRec *raw)
150
 
{
151
 
   fclose(raw->file);
152
 
   free(raw->tmp);
153
 
   free(raw->tmpR);
154
 
   free(raw->tmpG);
155
 
   free(raw->tmpB);
156
 
   if (raw->rowStart)
157
 
      free(raw->rowStart);
158
 
   if (raw->rowSize)
159
 
      free(raw->rowSize);
160
 
   if (raw->sizeZ>3) {
161
 
      free(raw->tmpA);
162
 
   }
163
 
   free(raw);
164
 
}
165
 
 
166
 
static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
167
 
{
168
 
   unsigned char *iPtr, *oPtr, pixel;
169
 
   int count, done = 0;
170
 
 
171
 
   if ((raw->type & 0xFF00) == 0x0100) {
172
 
      fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
173
 
      fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
174
 
            raw->file);
175
 
      
176
 
      iPtr = raw->tmp;
177
 
      oPtr = buf;
178
 
      while (!done) {
179
 
         pixel = *iPtr++;
180
 
         count = (int)(pixel & 0x7F);
181
 
         if (!count) {
182
 
                         done = 1;
183
 
            return;
184
 
         }
185
 
         if (pixel & 0x80) {
186
 
            while (count--) {
187
 
               *oPtr++ = *iPtr++;
188
 
            }
189
 
         } else {
190
 
            pixel = *iPtr++;
191
 
            while (count--) {
192
 
               *oPtr++ = pixel;
193
 
            }
194
 
         }
195
 
      }
196
 
   } else {
197
 
      fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
198
 
            SEEK_SET);
199
 
      fread(buf, 1, raw->sizeX, raw->file);
200
 
   }
201
 
}
202
 
 
203
 
 
204
 
static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
205
 
{
206
 
   unsigned char *ptr;
207
 
   int i, j;
208
 
 
209
 
   final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
210
 
   if (final->data == NULL) {
211
 
      fprintf(stderr, "Out of memory!\n");
212
 
   }
213
 
 
214
 
   ptr = final->data;
215
 
   for (i = 0; i < (int)(raw->sizeY); i++) {
216
 
      RawImageGetRow(raw, raw->tmpR, i, 0);
217
 
      RawImageGetRow(raw, raw->tmpG, i, 1);
218
 
      RawImageGetRow(raw, raw->tmpB, i, 2);
219
 
      if (raw->sizeZ>3) {
220
 
         RawImageGetRow(raw, raw->tmpA, i, 3);
221
 
      }
222
 
      for (j = 0; j < (int)(raw->sizeX); j++) {
223
 
         *ptr++ = *(raw->tmpR + j);
224
 
         *ptr++ = *(raw->tmpG + j);
225
 
         *ptr++ = *(raw->tmpB + j);
226
 
         if (raw->sizeZ>3) {
227
 
            *ptr++ = *(raw->tmpA + j);
228
 
         }
229
 
      }
230
 
   }
231
 
}
232
 
 
233
 
 
234
 
static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
235
 
{
236
 
   rawImageRec *raw;
237
 
   TK_RGBImageRec *final;
238
 
 
239
 
   raw = RawImageOpen(fileName);
240
 
   if (!raw) {
241
 
      fprintf(stderr, "File not found\n");
242
 
      return NULL;
243
 
   }
244
 
   final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
245
 
   if (final == NULL) {
246
 
      fprintf(stderr, "Out of memory!\n");
247
 
      return NULL;
248
 
   }
249
 
   final->sizeX = raw->sizeX;
250
 
   final->sizeY = raw->sizeY;
251
 
   final->components = raw->sizeZ;
252
 
   RawImageGetData(raw, final);
253
 
   RawImageClose(raw);
254
 
   return final;
255
 
}
256
 
 
257
 
 
258
 
static void FreeImage( TK_RGBImageRec *image )
259
 
{
260
 
   free(image->data);
261
 
   free(image);
262
 
}
263
 
 
264
 
 
265
 
/*
266
 
 * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
267
 
 * Input:  imageFile - name of .rgb to read
268
 
 *         intFormat - internal texture format to use, or number of components
269
 
 * Return:  GL_TRUE if success, GL_FALSE if error.
270
 
 */
271
 
GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
272
 
{
273
 
   GLint w, h;
274
 
   return LoadRGBMipmaps2( imageFile, GL_TEXTURE_2D, intFormat, &w, &h );
275
 
}
276
 
 
277
 
 
278
 
 
279
 
GLboolean LoadRGBMipmaps2( const char *imageFile, GLenum target,
280
 
                           GLint intFormat, GLint *width, GLint *height )
281
 
{
282
 
   GLint error;
283
 
   GLenum format;
284
 
   TK_RGBImageRec *image;
285
 
 
286
 
   image = tkRGBImageLoad( imageFile );
287
 
   if (!image) {
288
 
      return GL_FALSE;
289
 
   }
290
 
 
291
 
   if (image->components==3) {
292
 
      format = GL_RGB;
293
 
   }
294
 
   else if (image->components==4) {
295
 
      format = GL_RGBA;
296
 
   }
297
 
   else {
298
 
      /* not implemented */
299
 
      fprintf(stderr,
300
 
              "Error in LoadRGBMipmaps %d-component images not implemented\n",
301
 
              image->components );
302
 
      return GL_FALSE;
303
 
   }
304
 
 
305
 
   error = gluBuild2DMipmaps( target,
306
 
                              intFormat,
307
 
                              image->sizeX, image->sizeY,
308
 
                              format,
309
 
                              GL_UNSIGNED_BYTE,
310
 
                              image->data );
311
 
 
312
 
   *width = image->sizeX;
313
 
   *height = image->sizeY;
314
 
 
315
 
   FreeImage(image);
316
 
 
317
 
   return error ? GL_FALSE : GL_TRUE;
318
 
}
319
 
 
320
 
 
321
 
 
322
 
/*
323
 
 * Load an SGI .rgb file and return a pointer to the image data.
324
 
 * Input:  imageFile - name of .rgb to read
325
 
 * Output:  width - width of image
326
 
 *          height - height of image
327
 
 *          format - format of image (GL_RGB or GL_RGBA)
328
 
 * Return:  pointer to image data or NULL if error
329
 
 */
330
 
GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
331
 
                       GLenum *format )
332
 
{
333
 
   TK_RGBImageRec *image;
334
 
   GLint bytes;
335
 
   GLubyte *buffer;
336
 
 
337
 
   image = tkRGBImageLoad( imageFile );
338
 
   if (!image) {
339
 
      return NULL;
340
 
   }
341
 
 
342
 
   if (image->components==3) {
343
 
      *format = GL_RGB;
344
 
   }
345
 
   else if (image->components==4) {
346
 
      *format = GL_RGBA;
347
 
   }
348
 
   else {
349
 
      /* not implemented */
350
 
      fprintf(stderr,
351
 
              "Error in LoadRGBImage %d-component images not implemented\n",
352
 
              image->components );
353
 
      return NULL;
354
 
   }
355
 
 
356
 
   *width = image->sizeX;
357
 
   *height = image->sizeY;
358
 
 
359
 
   bytes = image->sizeX * image->sizeY * image->components;
360
 
   buffer = (GLubyte *) malloc(bytes);
361
 
   if (!buffer)
362
 
      return NULL;
363
 
 
364
 
   memcpy( (void *) buffer, (void *) image->data, bytes );
365
 
 
366
 
   FreeImage(image);
367
 
 
368
 
   return buffer;
369
 
}
370
 
 
371
 
#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
372
 
 
373
 
 
374
 
static void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes,
375
 
                            const GLubyte *src,
376
 
                            GLushort *dest)
377
 
{
378
 
   GLint i, j;
379
 
 
380
 
   for (i = 0; i < h; i++) {
381
 
      for (j = 0; j < w; j++) {
382
 
         const GLfloat r = (src[0]) / 255.0;
383
 
         const GLfloat g = (src[1]) / 255.0;
384
 
         const GLfloat b = (src[2]) / 255.0;
385
 
         GLfloat y, cr, cb;
386
 
         GLint iy, icr, icb;
387
 
 
388
 
         y  = r * 65.481 + g * 128.553 + b * 24.966 + 16;
389
 
         cb = r * -37.797 + g * -74.203 + b * 112.0 + 128;
390
 
         cr = r * 112.0 + g * -93.786 + b * -18.214 + 128;
391
 
         /*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/
392
 
         iy  = (GLint) CLAMP(y,  0, 254);
393
 
         icb = (GLint) CLAMP(cb, 0, 254);
394
 
         icr = (GLint) CLAMP(cr, 0, 254);
395
 
 
396
 
         if (j & 1) {
397
 
            /* odd */
398
 
            *dest = (iy << 8) | icr;
399
 
         }
400
 
         else {
401
 
            /* even */
402
 
            *dest = (iy << 8) | icb;
403
 
         }
404
 
         dest++;
405
 
         src += texel_bytes;
406
 
      }
407
 
   }
408
 
}
409
 
 
410
 
 
411
 
/*
412
 
 * Load an SGI .rgb file and return a pointer to the image data, converted
413
 
 * to 422 yuv.
414
 
 *
415
 
 * Input:  imageFile - name of .rgb to read
416
 
 * Output:  width - width of image
417
 
 *          height - height of image
418
 
 * Return:  pointer to image data or NULL if error
419
 
 */
420
 
GLushort *LoadYUVImage( const char *imageFile, GLint *width, GLint *height )
421
 
{
422
 
   TK_RGBImageRec *image;
423
 
   GLushort *buffer;
424
 
 
425
 
   image = tkRGBImageLoad( imageFile );
426
 
   if (!image) {
427
 
      return NULL;
428
 
   }
429
 
 
430
 
   if (image->components != 3 && image->components !=4 ) {
431
 
      /* not implemented */
432
 
      fprintf(stderr,
433
 
              "Error in LoadYUVImage %d-component images not implemented\n",
434
 
              image->components );
435
 
      return NULL;
436
 
   }
437
 
 
438
 
   *width = image->sizeX;
439
 
   *height = image->sizeY;
440
 
 
441
 
   buffer = (GLushort *) malloc( image->sizeX * image->sizeY * 2 );
442
 
 
443
 
   if (buffer)
444
 
      ConvertRGBtoYUV( image->sizeX, 
445
 
                       image->sizeY,
446
 
                       image->components,
447
 
                       image->data, 
448
 
                       buffer );
449
 
 
450
 
 
451
 
   FreeImage(image);
452
 
   return buffer;
453
 
}
454