Initial revision
This commit is contained in:
273
progs/samples/rgbtoppm.c
Normal file
273
progs/samples/rgbtoppm.c
Normal file
@@ -0,0 +1,273 @@
|
||||
|
||||
/* texture.c - by David Blythe, SGI */
|
||||
|
||||
/* texload is a simplistic routine for reading an SGI .rgb image file. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
typedef struct _ImageRec {
|
||||
unsigned short imagic;
|
||||
unsigned short type;
|
||||
unsigned short dim;
|
||||
unsigned short xsize, ysize, zsize;
|
||||
unsigned int min, max;
|
||||
unsigned int wasteBytes;
|
||||
char name[80];
|
||||
unsigned long colorMap;
|
||||
FILE *file;
|
||||
unsigned char *tmp;
|
||||
unsigned long rleEnd;
|
||||
unsigned int *rowStart;
|
||||
int *rowSize;
|
||||
} ImageRec;
|
||||
|
||||
void
|
||||
rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
|
||||
while(n--) {
|
||||
l[0] = r[0];
|
||||
l[1] = g[0];
|
||||
l[2] = b[0];
|
||||
l += 3; r++; g++; b++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ConvertShort(unsigned short *array, unsigned int length) {
|
||||
unsigned short b1, b2;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = (unsigned char *)array;
|
||||
while (length--) {
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
*array++ = (b1 << 8) | (b2);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ConvertUint(unsigned *array, unsigned int length) {
|
||||
unsigned int b1, b2, b3, b4;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = (unsigned char *)array;
|
||||
while (length--) {
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
b3 = *ptr++;
|
||||
b4 = *ptr++;
|
||||
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
|
||||
}
|
||||
}
|
||||
|
||||
static ImageRec *ImageOpen(char *fileName)
|
||||
{
|
||||
union {
|
||||
int testWord;
|
||||
char testByte[4];
|
||||
} endianTest;
|
||||
ImageRec *image;
|
||||
int swapFlag;
|
||||
int x;
|
||||
|
||||
endianTest.testWord = 1;
|
||||
if (endianTest.testByte[0] == 1) {
|
||||
swapFlag = 1;
|
||||
} else {
|
||||
swapFlag = 0;
|
||||
}
|
||||
|
||||
image = (ImageRec *)malloc(sizeof(ImageRec));
|
||||
if (image == NULL) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((image->file = fopen(fileName, "rb")) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fread(image, 1, 12, image->file);
|
||||
|
||||
if (swapFlag) {
|
||||
ConvertShort(&image->imagic, 6);
|
||||
}
|
||||
|
||||
image->tmp = (unsigned char *)malloc(image->xsize*256);
|
||||
if (image->tmp == NULL) {
|
||||
fprintf(stderr, "\nOut of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((image->type & 0xFF00) == 0x0100) {
|
||||
x = image->ysize * image->zsize * (int) sizeof(unsigned);
|
||||
image->rowStart = (unsigned *)malloc(x);
|
||||
image->rowSize = (int *)malloc(x);
|
||||
if (image->rowStart == NULL || image->rowSize == NULL) {
|
||||
fprintf(stderr, "\nOut of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
image->rleEnd = 512 + (2 * x);
|
||||
fseek(image->file, 512, SEEK_SET);
|
||||
fread(image->rowStart, 1, x, image->file);
|
||||
fread(image->rowSize, 1, x, image->file);
|
||||
if (swapFlag) {
|
||||
ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
|
||||
ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
ImageClose(ImageRec *image) {
|
||||
fclose(image->file);
|
||||
free(image->tmp);
|
||||
free(image);
|
||||
}
|
||||
|
||||
static void
|
||||
ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
|
||||
unsigned char *iPtr, *oPtr, pixel;
|
||||
int count;
|
||||
|
||||
if ((image->type & 0xFF00) == 0x0100) {
|
||||
fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
|
||||
fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
|
||||
image->file);
|
||||
|
||||
iPtr = image->tmp;
|
||||
oPtr = buf;
|
||||
for (;;) {
|
||||
pixel = *iPtr++;
|
||||
count = (int)(pixel & 0x7F);
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
if (pixel & 0x80) {
|
||||
while (count--) {
|
||||
*oPtr++ = *iPtr++;
|
||||
}
|
||||
} else {
|
||||
pixel = *iPtr++;
|
||||
while (count--) {
|
||||
*oPtr++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
|
||||
SEEK_SET);
|
||||
fread(buf, 1, image->xsize, image->file);
|
||||
}
|
||||
}
|
||||
|
||||
GLubyte *
|
||||
read_alpha_texture(char *name, int *width, int *height)
|
||||
{
|
||||
unsigned char *base, *lptr;
|
||||
ImageRec *image;
|
||||
int y;
|
||||
|
||||
image = ImageOpen(name);
|
||||
if(!image) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*width)=image->xsize;
|
||||
(*height)=image->ysize;
|
||||
if (image->zsize != 1) {
|
||||
ImageClose(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
|
||||
lptr = base;
|
||||
for(y=0; y<image->ysize; y++) {
|
||||
ImageGetRow(image,lptr,y,0);
|
||||
lptr += image->xsize;
|
||||
}
|
||||
ImageClose(image);
|
||||
|
||||
return (unsigned char *) base;
|
||||
}
|
||||
|
||||
GLubyte *
|
||||
read_rgb_texture(char *name, int *width, int *height)
|
||||
{
|
||||
unsigned char *base, *ptr;
|
||||
unsigned char *rbuf, *gbuf, *bbuf, *abuf;
|
||||
ImageRec *image;
|
||||
int y;
|
||||
|
||||
image = ImageOpen(name);
|
||||
|
||||
if(!image)
|
||||
return NULL;
|
||||
(*width)=image->xsize;
|
||||
(*height)=image->ysize;
|
||||
if (image->zsize != 3 && image->zsize != 4) {
|
||||
ImageClose(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
|
||||
rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
|
||||
gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
|
||||
bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
|
||||
abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
|
||||
if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
|
||||
if (base) free(base);
|
||||
if (rbuf) free(rbuf);
|
||||
if (gbuf) free(gbuf);
|
||||
if (bbuf) free(bbuf);
|
||||
if (abuf) free(abuf);
|
||||
return NULL;
|
||||
}
|
||||
ptr = base;
|
||||
for(y=0; y<image->ysize; y++) {
|
||||
if(image->zsize == 4) {
|
||||
ImageGetRow(image,rbuf,y,0);
|
||||
ImageGetRow(image,gbuf,y,1);
|
||||
ImageGetRow(image,bbuf,y,2);
|
||||
ImageGetRow(image,abuf,y,3); /* Discard. */
|
||||
rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
|
||||
ptr += (image->xsize * 3);
|
||||
} else {
|
||||
ImageGetRow(image,rbuf,y,0);
|
||||
ImageGetRow(image,gbuf,y,1);
|
||||
ImageGetRow(image,bbuf,y,2);
|
||||
rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
|
||||
ptr += (image->xsize * 3);
|
||||
}
|
||||
}
|
||||
ImageClose(image);
|
||||
free(rbuf);
|
||||
free(gbuf);
|
||||
free(bbuf);
|
||||
free(abuf);
|
||||
|
||||
return (GLubyte *) base;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int width, height;
|
||||
GLubyte *data;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "usage: %s <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
data = read_rgb_texture(argv[1], &width, &height);
|
||||
|
||||
printf("P6\n%d %d\n255\n", width, height);
|
||||
fwrite(data, width * 3, height, stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user