From 9cd57b731ab1c666d4a1cb725538fdc137763d12 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sat, 30 Jul 2011 11:19:14 -0400 Subject: Initial commit (version 0.2.1) --- libs/cocos2d/Support/TGAlib.m | 274 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100755 libs/cocos2d/Support/TGAlib.m (limited to 'libs/cocos2d/Support/TGAlib.m') diff --git a/libs/cocos2d/Support/TGAlib.m b/libs/cocos2d/Support/TGAlib.m new file mode 100755 index 0000000..11303b4 --- /dev/null +++ b/libs/cocos2d/Support/TGAlib.m @@ -0,0 +1,274 @@ +// +// TGA lib for cocos2d-iphone +// +// sources from: http://www.lighthouse3d.com/opengl/terrain/index.php3?tgasource +// +// TGA RLE compression support by Ernesto Corvi + +#include +#include +#include + +#import "TGAlib.h" + +void tgaLoadRLEImageData(FILE *file, tImageTGA *info); +void tgaFlipImage( tImageTGA *info ); + +// load the image header fields. We only keep those that matter! +void tgaLoadHeader(FILE *file, tImageTGA *info) { + unsigned char cGarbage; + short int iGarbage; + + fread(&cGarbage, sizeof(unsigned char), 1, file); + fread(&cGarbage, sizeof(unsigned char), 1, file); + + // type must be 2 or 3 + fread(&info->type, sizeof(unsigned char), 1, file); + + fread(&iGarbage, sizeof(short int), 1, file); + fread(&iGarbage, sizeof(short int), 1, file); + fread(&cGarbage, sizeof(unsigned char), 1, file); + fread(&iGarbage, sizeof(short int), 1, file); + fread(&iGarbage, sizeof(short int), 1, file); + + fread(&info->width, sizeof(short int), 1, file); + fread(&info->height, sizeof(short int), 1, file); + fread(&info->pixelDepth, sizeof(unsigned char), 1, file); + + fread(&cGarbage, sizeof(unsigned char), 1, file); + + info->flipped = 0; + if ( cGarbage & 0x20 ) info->flipped = 1; +} + +// loads the image pixels. You shouldn't call this function directly +void tgaLoadImageData(FILE *file, tImageTGA *info) { + + int mode,total,i; + unsigned char aux; + + // mode equal the number of components for each pixel + mode = info->pixelDepth / 8; + // total is the number of unsigned chars we'll have to read + total = info->height * info->width * mode; + + fread(info->imageData,sizeof(unsigned char),total,file); + + // mode=3 or 4 implies that the image is RGB(A). However TGA + // stores it as BGR(A) so we'll have to swap R and B. + if (mode >= 3) + for (i=0; i < total; i+= mode) { + aux = info->imageData[i]; + info->imageData[i] = info->imageData[i+2]; + info->imageData[i+2] = aux; + } +} + +// loads the RLE encoded image pixels. You shouldn't call this function directly +void tgaLoadRLEImageData(FILE *file, tImageTGA *info) +{ + unsigned int mode,total,i, index = 0; + unsigned char aux[4], runlength = 0; + unsigned int skip = 0, flag = 0; + + // mode equal the number of components for each pixel + mode = info->pixelDepth / 8; + // total is the number of unsigned chars we'll have to read + total = info->height * info->width; + + for( i = 0; i < total; i++ ) + { + // if we have a run length pending, run it + if ( runlength != 0 ) + { + // we do, update the run length count + runlength--; + skip = (flag != 0); + } + else + { + // otherwise, read in the run length token + if ( fread(&runlength,sizeof(unsigned char),1,file) != 1 ) + return; + + // see if it's a RLE encoded sequence + flag = runlength & 0x80; + if ( flag ) runlength -= 128; + skip = 0; + } + + // do we need to skip reading this pixel? + if ( !skip ) + { + // no, read in the pixel data + if ( fread(aux,sizeof(unsigned char),mode,file) != mode ) + return; + + // mode=3 or 4 implies that the image is RGB(A). However TGA + // stores it as BGR(A) so we'll have to swap R and B. + if ( mode >= 3 ) + { + unsigned char tmp; + + tmp = aux[0]; + aux[0] = aux[2]; + aux[2] = tmp; + } + } + + // add the pixel to our image + memcpy(&info->imageData[index], aux, mode); + index += mode; + } +} + +void tgaFlipImage( tImageTGA *info ) +{ + // mode equal the number of components for each pixel + int mode = info->pixelDepth / 8; + int rowbytes = info->width*mode; + unsigned char *row = (unsigned char *)malloc(rowbytes); + int y; + + if (row == NULL) return; + + for( y = 0; y < (info->height/2); y++ ) + { + memcpy(row, &info->imageData[y*rowbytes],rowbytes); + memcpy(&info->imageData[y*rowbytes], &info->imageData[(info->height-(y+1))*rowbytes], rowbytes); + memcpy(&info->imageData[(info->height-(y+1))*rowbytes], row, rowbytes); + } + + free(row); + info->flipped = 0; +} + +// this is the function to call when we want to load an image +tImageTGA * tgaLoad(const char *filename) { + + FILE *file; + tImageTGA *info; + int mode,total; + + // allocate memory for the info struct and check! + info = (tImageTGA *)malloc(sizeof(tImageTGA)); + if (info == NULL) + return(NULL); + + + // open the file for reading (binary mode) + file = fopen(filename, "rb"); + if (file == NULL) { + info->status = TGA_ERROR_FILE_OPEN; + return(info); + } + + // load the header + tgaLoadHeader(file,info); + + // check for errors when loading the header + if (ferror(file)) { + info->status = TGA_ERROR_READING_FILE; + fclose(file); + return(info); + } + + // check if the image is color indexed + if (info->type == 1) { + info->status = TGA_ERROR_INDEXED_COLOR; + fclose(file); + return(info); + } + // check for other types (compressed images) + if ((info->type != 2) && (info->type !=3) && (info->type !=10) ) { + info->status = TGA_ERROR_COMPRESSED_FILE; + fclose(file); + return(info); + } + + // mode equals the number of image components + mode = info->pixelDepth / 8; + // total is the number of unsigned chars to read + total = info->height * info->width * mode; + // allocate memory for image pixels + info->imageData = (unsigned char *)malloc(sizeof(unsigned char) * + total); + + // check to make sure we have the memory required + if (info->imageData == NULL) { + info->status = TGA_ERROR_MEMORY; + fclose(file); + return(info); + } + // finally load the image pixels + if ( info->type == 10 ) + tgaLoadRLEImageData(file, info); + else + tgaLoadImageData(file,info); + + // check for errors when reading the pixels + if (ferror(file)) { + info->status = TGA_ERROR_READING_FILE; + fclose(file); + return(info); + } + fclose(file); + info->status = TGA_OK; + + if ( info->flipped ) + { + tgaFlipImage( info ); + if ( info->flipped ) info->status = TGA_ERROR_MEMORY; + } + + return(info); +} + +// converts RGB to greyscale +void tgaRGBtogreyscale(tImageTGA *info) { + + int mode,i,j; + + unsigned char *newImageData; + + // if the image is already greyscale do nothing + if (info->pixelDepth == 8) + return; + + // compute the number of actual components + mode = info->pixelDepth / 8; + + // allocate an array for the new image data + newImageData = (unsigned char *)malloc(sizeof(unsigned char) * + info->height * info->width); + if (newImageData == NULL) { + return; + } + + // convert pixels: greyscale = o.30 * R + 0.59 * G + 0.11 * B + for (i = 0,j = 0; j < info->width * info->height; i +=mode, j++) + newImageData[j] = + (unsigned char)(0.30 * info->imageData[i] + + 0.59 * info->imageData[i+1] + + 0.11 * info->imageData[i+2]); + + + //free old image data + free(info->imageData); + + // reassign pixelDepth and type according to the new image type + info->pixelDepth = 8; + info->type = 3; + // reassing imageData to the new array. + info->imageData = newImageData; +} + +// releases the memory used for the image +void tgaDestroy(tImageTGA *info) { + + if (info != NULL) { + if (info->imageData != NULL) + free(info->imageData); + free(info); + } +} -- cgit 1.4.1