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

GIS编程

开发平台:

Visual C++

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