texture.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:8k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* texture.c - by David Blythe, SGI */
  2. /* read_texture is a simplistic routine for reading an SGI .rgb image file. */
  3. #include <stdio.h>
  4. #include <stdlib.h> 
  5. #include <string.h>
  6. #include <GL/glut.h>
  7. void
  8. bwtorgba(unsigned char *b,unsigned char *l,int n) {
  9.     while(n--) {
  10.         l[0] = *b;
  11.         l[1] = *b;
  12.         l[2] = *b;
  13.         l[3] = 0xff;
  14.         l += 4; b++;
  15.     }
  16. }
  17. void
  18. rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
  19.     while(n--) {
  20.         l[0] = r[0];
  21.         l[1] = g[0];
  22.         l[2] = b[0];
  23.         l[3] = 0xff;
  24.         l += 4; r++; g++; b++;
  25.     }
  26. }
  27. void
  28. rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
  29.     while(n--) {
  30.         l[0] = r[0];
  31.         l[1] = g[0];
  32.         l[2] = b[0];
  33.         l[3] = a[0];
  34.         l += 4; r++; g++; b++; a++;
  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. static void
  53. ConvertShort(unsigned short *array, unsigned int length) {
  54.     unsigned short b1, b2;
  55.     unsigned char *ptr;
  56.     ptr = (unsigned char *)array;
  57.     while (length--) {
  58.         b1 = *ptr++;
  59.         b2 = *ptr++;
  60.         *array++ = (b1 << 8) | (b2);
  61.     }
  62. }
  63. static void
  64. ConvertUint(unsigned *array, unsigned int length) {
  65.     unsigned int b1, b2, b3, b4;
  66.     unsigned char *ptr;
  67.     ptr = (unsigned char *)array;
  68.     while (length--) {
  69.         b1 = *ptr++;
  70.         b2 = *ptr++;
  71.         b3 = *ptr++;
  72.         b4 = *ptr++;
  73.         *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  74.     }
  75. }
  76. static ImageRec *ImageOpen(char *fileName)
  77. {
  78.     union {
  79.         int testWord;
  80.         char testByte[4];
  81.     } endianTest;
  82.     ImageRec *image;
  83.     int swapFlag;
  84.     int x;
  85.     endianTest.testWord = 1;
  86.     if (endianTest.testByte[0] == 1) {
  87.         swapFlag = 1;
  88.     } else {
  89.         swapFlag = 0;
  90.     }
  91.     image = (ImageRec *)malloc(sizeof(ImageRec));
  92.     if (image == NULL) {
  93.         fprintf(stderr, "Out of memory!n");
  94.         exit(1);
  95.     }
  96.     if ((image->file = fopen(fileName, "rb")) == NULL) {
  97.         perror(fileName);
  98.         exit(1);
  99.     }
  100.     fread(image, 1, 12, image->file);
  101.     if (swapFlag) {
  102.         ConvertShort(&image->imagic, 6);
  103.     }
  104.     image->tmp = (unsigned char *)malloc(image->xsize*256);
  105.     image->tmpR = (unsigned char *)malloc(image->xsize*256);
  106.     image->tmpG = (unsigned char *)malloc(image->xsize*256);
  107.     image->tmpB = (unsigned char *)malloc(image->xsize*256);
  108.     if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
  109.         image->tmpB == NULL) {
  110.         fprintf(stderr, "Out of memory!n");
  111.         exit(1);
  112.     }
  113.     if ((image->type & 0xFF00) == 0x0100) {
  114.         x = image->ysize * image->zsize * (int) sizeof(unsigned);
  115.         image->rowStart = (unsigned *)malloc(x);
  116.         image->rowSize = (int *)malloc(x);
  117.         if (image->rowStart == NULL || image->rowSize == NULL) {
  118.             fprintf(stderr, "Out of memory!n");
  119.             exit(1);
  120.         }
  121.         image->rleEnd = 512 + (2 * x);
  122.         fseek(image->file, 512, SEEK_SET);
  123.         fread(image->rowStart, 1, x, image->file);
  124.         fread(image->rowSize, 1, x, image->file);
  125.         if (swapFlag) {
  126.             ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
  127.             ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
  128.         }
  129.     }
  130.     return image;
  131. }
  132. static void
  133. ImageClose(ImageRec *image) {
  134.     fclose(image->file);
  135.     free(image->tmp);
  136.     free(image->tmpR);
  137.     free(image->tmpG);
  138.     free(image->tmpB);
  139.     free(image);
  140. }
  141. static void
  142. ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
  143.     unsigned char *iPtr, *oPtr, pixel;
  144.     int count;
  145.     if ((image->type & 0xFF00) == 0x0100) {
  146.         fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
  147.         fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
  148.               image->file);
  149.         iPtr = image->tmp;
  150.         oPtr = buf;
  151.         for (;;) {
  152.             pixel = *iPtr++;
  153.             count = (int)(pixel & 0x7F);
  154.             if (!count) {
  155.                 return;
  156.             }
  157.             if (pixel & 0x80) {
  158.                 while (count--) {
  159.                     *oPtr++ = *iPtr++;
  160.                 }
  161.             } else {
  162.                 pixel = *iPtr++;
  163.                 while (count--) {
  164.                     *oPtr++ = pixel;
  165.                 }
  166.             }
  167.         }
  168.     } else {
  169.         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
  170.               SEEK_SET);
  171.         fread(buf, 1, image->xsize, image->file);
  172.     }
  173. }
  174. unsigned *
  175. read_texture(char *name, int *width, int *height, int *components) {
  176.     unsigned *base, *lptr;
  177.     unsigned char *rbuf, *gbuf, *bbuf, *abuf;
  178.     ImageRec *image;
  179.     int y;
  180.     image = ImageOpen(name);
  181.     
  182.     if(!image)
  183.         return NULL;
  184.     (*width)=image->xsize;
  185.     (*height)=image->ysize;
  186.     (*components)=image->zsize;
  187.     base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
  188.     rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  189.     gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  190.     bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  191.     abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  192.     if(!base || !rbuf || !gbuf || !bbuf)
  193.       return NULL;
  194.     lptr = base;
  195.     for(y=0; y<image->ysize; y++) {
  196.         if(image->zsize>=4) {
  197.             ImageGetRow(image,rbuf,y,0);
  198.             ImageGetRow(image,gbuf,y,1);
  199.             ImageGetRow(image,bbuf,y,2);
  200.             ImageGetRow(image,abuf,y,3);
  201.             rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
  202.             lptr += image->xsize;
  203.         } else if(image->zsize==3) {
  204.             ImageGetRow(image,rbuf,y,0);
  205.             ImageGetRow(image,gbuf,y,1);
  206.             ImageGetRow(image,bbuf,y,2);
  207.             rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
  208.             lptr += image->xsize;
  209.         } else {
  210.             ImageGetRow(image,rbuf,y,0);
  211.             bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
  212.             lptr += image->xsize;
  213.         }
  214.     }
  215.     ImageClose(image);
  216.     free(rbuf);
  217.     free(gbuf);
  218.     free(bbuf);
  219.     free(abuf);
  220.     return (unsigned *) base;
  221. }
  222. void imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4],
  223.   int *wOut, int *hOut, GLubyte ** imgOut)
  224. {
  225.   int border = borderIn;
  226.   int width, height;
  227.   int w, h;
  228.   GLubyte *image, *img, *p;
  229.   int i, j, components;
  230.   image = (GLubyte *) read_texture(filenameIn, &width, &height, &components);
  231.   w = width + 2 * border;
  232.   h = height + 2 * border;
  233.   img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char));
  234.   p = img;
  235.   for (j = -border; j < height + border; ++j) {
  236.     for (i = -border; i < width + border; ++i) {
  237.       if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) {
  238.         p[0] = image[4 * (j * width + i) + 0];
  239.         p[1] = image[4 * (j * width + i) + 1];
  240.         p[2] = image[4 * (j * width + i) + 2];
  241.         p[3] = 0xff;
  242.       } else {
  243.         p[0] = borderColorIn[0] * 0xff;
  244.         p[1] = borderColorIn[1] * 0xff;
  245.         p[2] = borderColorIn[2] * 0xff;
  246.         p[3] = borderColorIn[3] * 0xff;
  247.       }
  248.       p += 4;
  249.     }
  250.   }
  251.   free(image);
  252.   *wOut = w;
  253.   *hOut = h;
  254.   *imgOut = img;
  255. }