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

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. void
  7. bwtorgba(unsigned char *b,unsigned char *l,int n) {
  8.     while(n--) {
  9.         l[0] = *b;
  10.         l[1] = *b;
  11.         l[2] = *b;
  12.         l[3] = 0xff;
  13.         l += 4; b++;
  14.     }
  15. }
  16. void
  17. rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
  18.     while(n--) {
  19.         l[0] = r[0];
  20.         l[1] = g[0];
  21.         l[2] = b[0];
  22.         l[3] = 0xff;
  23.         l += 4; r++; g++; b++;
  24.     }
  25. }
  26. void
  27. rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
  28.     while(n--) {
  29.         l[0] = r[0];
  30.         l[1] = g[0];
  31.         l[2] = b[0];
  32.         l[3] = a[0];
  33.         l += 4; r++; g++; b++; a++;
  34.     }
  35. }
  36. typedef struct _ImageRec {
  37.     unsigned short imagic;
  38.     unsigned short type;
  39.     unsigned short dim;
  40.     unsigned short xsize, ysize, zsize;
  41.     unsigned int min, max;
  42.     unsigned int wasteBytes;
  43.     char name[80];
  44.     unsigned long colorMap;
  45.     FILE *file;
  46.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  47.     unsigned long rleEnd;
  48.     unsigned int *rowStart;
  49.     int *rowSize;
  50. } ImageRec;
  51. static void
  52. ConvertShort(unsigned short *array, unsigned int length) {
  53.     unsigned short b1, b2;
  54.     unsigned char *ptr;
  55.     ptr = (unsigned char *)array;
  56.     while (length--) {
  57.         b1 = *ptr++;
  58.         b2 = *ptr++;
  59.         *array++ = (b1 << 8) | (b2);
  60.     }
  61. }
  62. static void
  63. ConvertUint(unsigned *array, unsigned int length) {
  64.     unsigned int b1, b2, b3, b4;
  65.     unsigned char *ptr;
  66.     ptr = (unsigned char *)array;
  67.     while (length--) {
  68.         b1 = *ptr++;
  69.         b2 = *ptr++;
  70.         b3 = *ptr++;
  71.         b4 = *ptr++;
  72.         *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  73.     }
  74. }
  75. static ImageRec *ImageOpen(char *fileName)
  76. {
  77.     union {
  78.         int testWord;
  79.         char testByte[4];
  80.     } endianTest;
  81.     ImageRec *image;
  82.     int swapFlag;
  83.     int x;
  84.     endianTest.testWord = 1;
  85.     if (endianTest.testByte[0] == 1) {
  86.         swapFlag = 1;
  87.     } else {
  88.         swapFlag = 0;
  89.     }
  90.     image = (ImageRec *)malloc(sizeof(ImageRec));
  91.     if (image == NULL) {
  92.         fprintf(stderr, "Out of memory!n");
  93.         exit(1);
  94.     }
  95.     if ((image->file = fopen(fileName, "rb")) == NULL) {
  96.         perror(fileName);
  97.         exit(1);
  98.     }
  99.     fread(image, 1, 12, image->file);
  100.     if (swapFlag) {
  101.         ConvertShort(&image->imagic, 6);
  102.     }
  103.     image->tmp = (unsigned char *)malloc(image->xsize*256);
  104.     image->tmpR = (unsigned char *)malloc(image->xsize*256);
  105.     image->tmpG = (unsigned char *)malloc(image->xsize*256);
  106.     image->tmpB = (unsigned char *)malloc(image->xsize*256);
  107.     if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
  108.         image->tmpB == NULL) {
  109.         fprintf(stderr, "Out of memory!n");
  110.         exit(1);
  111.     }
  112.     if ((image->type & 0xFF00) == 0x0100) {
  113.         x = image->ysize * image->zsize * (int) sizeof(unsigned);
  114.         image->rowStart = (unsigned *)malloc(x);
  115.         image->rowSize = (int *)malloc(x);
  116.         if (image->rowStart == NULL || image->rowSize == NULL) {
  117.             fprintf(stderr, "Out of memory!n");
  118.             exit(1);
  119.         }
  120.         image->rleEnd = 512 + (2 * x);
  121.         fseek(image->file, 512, SEEK_SET);
  122.         fread(image->rowStart, 1, x, image->file);
  123.         fread(image->rowSize, 1, x, image->file);
  124.         if (swapFlag) {
  125.             ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
  126.             ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
  127.         }
  128.     }
  129.     return image;
  130. }
  131. static void
  132. ImageClose(ImageRec *image) {
  133.     fclose(image->file);
  134.     free(image->tmp);
  135.     free(image->tmpR);
  136.     free(image->tmpG);
  137.     free(image->tmpB);
  138.     free(image);
  139. }
  140. static void
  141. ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
  142.     unsigned char *iPtr, *oPtr, pixel;
  143.     int count;
  144.     if ((image->type & 0xFF00) == 0x0100) {
  145.         fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
  146.         fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
  147.               image->file);
  148.         iPtr = image->tmp;
  149.         oPtr = buf;
  150.         for (;;) {
  151.             pixel = *iPtr++;
  152.             count = (int)(pixel & 0x7F);
  153.             if (!count) {
  154.                 return;
  155.             }
  156.             if (pixel & 0x80) {
  157.                 while (count--) {
  158.                     *oPtr++ = *iPtr++;
  159.                 }
  160.             } else {
  161.                 pixel = *iPtr++;
  162.                 while (count--) {
  163.                     *oPtr++ = pixel;
  164.                 }
  165.             }
  166.         }
  167.     } else {
  168.         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
  169.               SEEK_SET);
  170.         fread(buf, 1, image->xsize, image->file);
  171.     }
  172. }
  173. unsigned *
  174. read_texture(char *name, int *width, int *height, int *components) {
  175.     unsigned *base, *lptr;
  176.     unsigned char *rbuf, *gbuf, *bbuf, *abuf;
  177.     ImageRec *image;
  178.     int y;
  179.     image = ImageOpen(name);
  180.     
  181.     if(!image)
  182.         return NULL;
  183.     (*width)=image->xsize;
  184.     (*height)=image->ysize;
  185.     (*components)=image->zsize;
  186.     base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
  187.     rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  188.     gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  189.     bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  190.     abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  191.     if(!base || !rbuf || !gbuf || !bbuf)
  192.       return NULL;
  193.     lptr = base;
  194.     for(y=0; y<image->ysize; y++) {
  195.         if(image->zsize>=4) {
  196.             ImageGetRow(image,rbuf,y,0);
  197.             ImageGetRow(image,gbuf,y,1);
  198.             ImageGetRow(image,bbuf,y,2);
  199.             ImageGetRow(image,abuf,y,3);
  200.             rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
  201.             lptr += image->xsize;
  202.         } else if(image->zsize==3) {
  203.             ImageGetRow(image,rbuf,y,0);
  204.             ImageGetRow(image,gbuf,y,1);
  205.             ImageGetRow(image,bbuf,y,2);
  206.             rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
  207.             lptr += image->xsize;
  208.         } else {
  209.             ImageGetRow(image,rbuf,y,0);
  210.             bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
  211.             lptr += image->xsize;
  212.         }
  213.     }
  214.     ImageClose(image);
  215.     free(rbuf);
  216.     free(gbuf);
  217.     free(bbuf);
  218.     free(abuf);
  219.     return (unsigned *) base;
  220. }