Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

readtex.c 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /* readtex.c */
  2. /*
  3. * Read an SGI .rgb image file and generate a mipmap texture set.
  4. * Much of this code was borrowed from SGI's tk OpenGL toolkit.
  5. */
  6. #include <GL/gl.h>
  7. #include <GL/glu.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #ifndef SEEK_SET
  12. # define SEEK_SET 0
  13. #endif
  14. /*
  15. ** RGB Image Structure
  16. */
  17. typedef struct _TK_RGBImageRec {
  18. GLint sizeX, sizeY;
  19. GLint components;
  20. unsigned char *data;
  21. } TK_RGBImageRec;
  22. /******************************************************************************/
  23. typedef struct _rawImageRec {
  24. unsigned short imagic;
  25. unsigned short type;
  26. unsigned short dim;
  27. unsigned short sizeX, sizeY, sizeZ;
  28. unsigned long min, max;
  29. unsigned long wasteBytes;
  30. char name[80];
  31. unsigned long colorMap;
  32. FILE *file;
  33. unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
  34. unsigned long rleEnd;
  35. GLuint *rowStart;
  36. GLint *rowSize;
  37. } rawImageRec;
  38. /******************************************************************************/
  39. static void ConvertShort(unsigned short *array, long length)
  40. {
  41. unsigned long b1, b2;
  42. unsigned char *ptr;
  43. ptr = (unsigned char *)array;
  44. while (length--) {
  45. b1 = *ptr++;
  46. b2 = *ptr++;
  47. *array++ = (unsigned short) ((b1 << 8) | (b2));
  48. }
  49. }
  50. static void ConvertLong(GLuint *array, long length)
  51. {
  52. unsigned long b1, b2, b3, b4;
  53. unsigned char *ptr;
  54. ptr = (unsigned char *)array;
  55. while (length--) {
  56. b1 = *ptr++;
  57. b2 = *ptr++;
  58. b3 = *ptr++;
  59. b4 = *ptr++;
  60. *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  61. }
  62. }
  63. static rawImageRec *RawImageOpen(const char *fileName)
  64. {
  65. union {
  66. int testWord;
  67. char testByte[4];
  68. } endianTest;
  69. rawImageRec *raw;
  70. GLenum swapFlag;
  71. int x;
  72. endianTest.testWord = 1;
  73. if (endianTest.testByte[0] == 1) {
  74. swapFlag = GL_TRUE;
  75. } else {
  76. swapFlag = GL_FALSE;
  77. }
  78. raw = (rawImageRec *)malloc(sizeof(rawImageRec));
  79. if (raw == NULL) {
  80. fprintf(stderr, "Out of memory!\n");
  81. return NULL;
  82. }
  83. if ((raw->file = fopen(fileName, "rb")) == NULL) {
  84. perror(fileName);
  85. return NULL;
  86. }
  87. fread(raw, 1, 12, raw->file);
  88. if (swapFlag) {
  89. ConvertShort(&raw->imagic, 6);
  90. }
  91. raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
  92. raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
  93. raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
  94. raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
  95. if (raw->sizeZ==4) {
  96. raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
  97. }
  98. if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
  99. raw->tmpB == NULL) {
  100. fprintf(stderr, "Out of memory!\n");
  101. return NULL;
  102. }
  103. if ((raw->type & 0xFF00) == 0x0100) {
  104. x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
  105. raw->rowStart = (GLuint *)malloc(x);
  106. raw->rowSize = (GLint *)malloc(x);
  107. if (raw->rowStart == NULL || raw->rowSize == NULL) {
  108. fprintf(stderr, "Out of memory!\n");
  109. return NULL;
  110. }
  111. raw->rleEnd = 512 + (2 * x);
  112. fseek(raw->file, 512, SEEK_SET);
  113. fread(raw->rowStart, 1, x, raw->file);
  114. fread(raw->rowSize, 1, x, raw->file);
  115. if (swapFlag) {
  116. ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
  117. ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
  118. }
  119. }
  120. return raw;
  121. }
  122. static void RawImageClose(rawImageRec *raw)
  123. {
  124. fclose(raw->file);
  125. free(raw->tmp);
  126. free(raw->tmpR);
  127. free(raw->tmpG);
  128. free(raw->tmpB);
  129. if (raw->sizeZ>3) {
  130. free(raw->tmpA);
  131. }
  132. free(raw);
  133. }
  134. static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
  135. {
  136. unsigned char *iPtr, *oPtr, pixel;
  137. int count, done = 0;
  138. if ((raw->type & 0xFF00) == 0x0100) {
  139. fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
  140. fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
  141. raw->file);
  142. iPtr = raw->tmp;
  143. oPtr = buf;
  144. while (!done) {
  145. pixel = *iPtr++;
  146. count = (int)(pixel & 0x7F);
  147. if (!count) {
  148. done = 1;
  149. return;
  150. }
  151. if (pixel & 0x80) {
  152. while (count--) {
  153. *oPtr++ = *iPtr++;
  154. }
  155. } else {
  156. pixel = *iPtr++;
  157. while (count--) {
  158. *oPtr++ = pixel;
  159. }
  160. }
  161. }
  162. } else {
  163. fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
  164. SEEK_SET);
  165. fread(buf, 1, raw->sizeX, raw->file);
  166. }
  167. }
  168. static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
  169. {
  170. unsigned char *ptr;
  171. int i, j;
  172. final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
  173. if (final->data == NULL) {
  174. fprintf(stderr, "Out of memory!\n");
  175. }
  176. ptr = final->data;
  177. for (i = 0; i < (int)(raw->sizeY); i++) {
  178. RawImageGetRow(raw, raw->tmpR, i, 0);
  179. RawImageGetRow(raw, raw->tmpG, i, 1);
  180. RawImageGetRow(raw, raw->tmpB, i, 2);
  181. if (raw->sizeZ>3) {
  182. RawImageGetRow(raw, raw->tmpA, i, 3);
  183. }
  184. for (j = 0; j < (int)(raw->sizeX); j++) {
  185. *ptr++ = *(raw->tmpR + j);
  186. *ptr++ = *(raw->tmpG + j);
  187. *ptr++ = *(raw->tmpB + j);
  188. if (raw->sizeZ>3) {
  189. *ptr++ = *(raw->tmpA + j);
  190. }
  191. }
  192. }
  193. }
  194. static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
  195. {
  196. rawImageRec *raw;
  197. TK_RGBImageRec *final;
  198. raw = RawImageOpen(fileName);
  199. if (!raw) {
  200. fprintf(stderr, "File not found\n");
  201. return NULL;
  202. }
  203. final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
  204. if (final == NULL) {
  205. fprintf(stderr, "Out of memory!\n");
  206. return NULL;
  207. }
  208. final->sizeX = raw->sizeX;
  209. final->sizeY = raw->sizeY;
  210. final->components = raw->sizeZ;
  211. RawImageGetData(raw, final);
  212. RawImageClose(raw);
  213. return final;
  214. }
  215. static void FreeImage( TK_RGBImageRec *image )
  216. {
  217. free(image->data);
  218. free(image);
  219. }
  220. /*
  221. * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
  222. * Input: imageFile - name of .rgb to read
  223. * intFormat - internal texture format to use, or number of components
  224. * Return: GL_TRUE if success, GL_FALSE if error.
  225. */
  226. GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
  227. {
  228. GLint error;
  229. GLenum format;
  230. TK_RGBImageRec *image;
  231. image = tkRGBImageLoad( imageFile );
  232. if (!image) {
  233. return GL_FALSE;
  234. }
  235. if (image->components==3) {
  236. format = GL_RGB;
  237. }
  238. else if (image->components==4) {
  239. format = GL_RGBA;
  240. }
  241. else {
  242. /* not implemented */
  243. fprintf(stderr,
  244. "Error in LoadRGBMipmaps %d-component images not implemented\n",
  245. image->components );
  246. return GL_FALSE;
  247. }
  248. error = gluBuild2DMipmaps( GL_TEXTURE_2D,
  249. intFormat,
  250. image->sizeX, image->sizeY,
  251. format,
  252. GL_UNSIGNED_BYTE,
  253. image->data );
  254. FreeImage(image);
  255. return error ? GL_FALSE : GL_TRUE;
  256. }
  257. /*
  258. * Load an SGI .rgb file and return a pointer to the image data.
  259. * Input: imageFile - name of .rgb to read
  260. * Output: width - width of image
  261. * height - height of image
  262. * format - format of image (GL_RGB or GL_RGBA)
  263. * Return: pointer to image data or NULL if error
  264. */
  265. GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
  266. GLenum *format )
  267. {
  268. TK_RGBImageRec *image;
  269. GLint bytes;
  270. GLubyte *buffer;
  271. image = tkRGBImageLoad( imageFile );
  272. if (!image) {
  273. return NULL;
  274. }
  275. if (image->components==3) {
  276. *format = GL_RGB;
  277. }
  278. else if (image->components==4) {
  279. *format = GL_RGBA;
  280. }
  281. else {
  282. /* not implemented */
  283. fprintf(stderr,
  284. "Error in LoadRGBImage %d-component images not implemented\n",
  285. image->components );
  286. return NULL;
  287. }
  288. *width = image->sizeX;
  289. *height = image->sizeY;
  290. bytes = image->sizeX * image->sizeY * image->components;
  291. buffer = (GLubyte *) malloc(bytes);
  292. if (!buffer)
  293. return NULL;
  294. memcpy( (void *) buffer, (void *) image->data, bytes );
  295. FreeImage(image);
  296. return buffer;
  297. }