Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rgbtoppm.c 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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 <GL/glut.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. if(!image)
  179. return NULL;
  180. (*width)=image->xsize;
  181. (*height)=image->ysize;
  182. if (image->zsize != 3 && image->zsize != 4) {
  183. ImageClose(image);
  184. return NULL;
  185. }
  186. base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
  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 || !abuf) {
  192. if (base) free(base);
  193. if (rbuf) free(rbuf);
  194. if (gbuf) free(gbuf);
  195. if (bbuf) free(bbuf);
  196. if (abuf) free(abuf);
  197. return NULL;
  198. }
  199. ptr = base;
  200. for(y=0; y<image->ysize; y++) {
  201. if(image->zsize == 4) {
  202. ImageGetRow(image,rbuf,y,0);
  203. ImageGetRow(image,gbuf,y,1);
  204. ImageGetRow(image,bbuf,y,2);
  205. ImageGetRow(image,abuf,y,3); /* Discard. */
  206. rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
  207. ptr += (image->xsize * 3);
  208. } else {
  209. ImageGetRow(image,rbuf,y,0);
  210. ImageGetRow(image,gbuf,y,1);
  211. ImageGetRow(image,bbuf,y,2);
  212. rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
  213. ptr += (image->xsize * 3);
  214. }
  215. }
  216. ImageClose(image);
  217. free(rbuf);
  218. free(gbuf);
  219. free(bbuf);
  220. free(abuf);
  221. return (GLubyte *) base;
  222. }
  223. int main(int argc, char **argv)
  224. {
  225. int width, height;
  226. GLubyte *data;
  227. if (argc != 2)
  228. {
  229. fprintf(stderr, "usage: %s <filename>\n", argv[0]);
  230. return 1;
  231. }
  232. data = read_rgb_texture(argv[1], &width, &height);
  233. printf("P6\n%d %d\n255\n", width, height);
  234. fwrite(data, width * 3, height, stdout);
  235. return 0;
  236. }