00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include "shared.h"
00015 #include "tga.h"
00016 #include "mmgr.h"
00017
00018
00019 static int savedImages=0;
00020
00021
00022 void tgaLoadHeader(FILE *file, tgaInfo *info) {
00023
00024 unsigned char cGarbage;
00025 short int iGarbage;
00026
00027 fread(&cGarbage, sizeof(unsigned char), 1, file);
00028 fread(&cGarbage, sizeof(unsigned char), 1, file);
00029
00030
00031 fread(&info->type, sizeof(unsigned char), 1, file);
00032
00033 fread(&iGarbage, sizeof(short int), 1, file);
00034 fread(&iGarbage, sizeof(short int), 1, file);
00035 fread(&cGarbage, sizeof(unsigned char), 1, file);
00036 fread(&iGarbage, sizeof(short int), 1, file);
00037 fread(&iGarbage, sizeof(short int), 1, file);
00038
00039 fread(&info->width, sizeof(short int), 1, file);
00040 fread(&info->height, sizeof(short int), 1, file);
00041 fread(&info->pixelDepth, sizeof(unsigned char), 1, file);
00042
00043 fread(&cGarbage, sizeof(unsigned char), 1, file);
00044 }
00045
00046
00047
00048 void tgaLoadImageData(FILE *file, tgaInfo *info) {
00049
00050 int mode,total,i;
00051 unsigned char aux;
00052
00053
00054 mode = info->pixelDepth / 8;
00055
00056 total = info->height * info->width * mode;
00057
00058 fread(info->imageData,sizeof(unsigned char),total,file);
00059
00060
00061
00062 if (mode >= 3)
00063 for (i=0; i < total; i+= mode) {
00064 aux = info->imageData[i];
00065 info->imageData[i] = info->imageData[i+2];
00066 info->imageData[i+2] = aux;
00067 }
00068 }
00069
00070
00071
00072 tgaInfo * tgaLoad(char *filename) {
00073
00074 FILE *file;
00075 tgaInfo *info;
00076 int mode,total;
00077
00078
00079 info = (tgaInfo *)malloc(sizeof(tgaInfo));
00080 if (info == NULL)
00081 return(NULL);
00082
00083
00084
00085 file = fopen(filename, "rb");
00086 if (file == NULL) {
00087 info->status = TGA_ERROR_FILE_OPEN;
00088 return(info);
00089 }
00090
00091
00092 tgaLoadHeader(file,info);
00093
00094
00095 if (ferror(file)) {
00096 info->status = TGA_ERROR_READING_FILE;
00097 fclose(file);
00098 return(info);
00099 }
00100
00101
00102 if (info->type == 1) {
00103 info->status = TGA_ERROR_INDEXED_COLOR;
00104 fclose(file);
00105 return(info);
00106 }
00107
00108 if ((info->type != 2) && (info->type !=3)) {
00109 info->status = TGA_ERROR_COMPRESSED_FILE;
00110 fclose(file);
00111 return(info);
00112 }
00113
00114
00115 mode = info->pixelDepth / 8;
00116
00117 total = info->height * info->width * mode;
00118
00119 info->imageData = (unsigned char *)malloc(sizeof(unsigned char) *
00120 total);
00121
00122
00123 if (info->imageData == NULL) {
00124 info->status = TGA_ERROR_MEMORY;
00125 fclose(file);
00126 return(info);
00127 }
00128
00129 tgaLoadImageData(file,info);
00130
00131
00132 if (ferror(file)) {
00133 info->status = TGA_ERROR_READING_FILE;
00134 fclose(file);
00135 return(info);
00136 }
00137 fclose(file);
00138 info->status = TGA_OK;
00139 return(info);
00140 }
00141
00142
00143 void tgaRGBtogreyscale(tgaInfo *info) {
00144
00145 int mode,i,j;
00146
00147 unsigned char *newImageData;
00148
00149
00150 if (info->pixelDepth == 8)
00151 return;
00152
00153
00154 mode = info->pixelDepth / 8;
00155
00156
00157 newImageData = (unsigned char *)malloc(sizeof(unsigned char) *
00158 info->height * info->width);
00159 if (newImageData == NULL) {
00160 return;
00161 }
00162
00163
00164 for (i = 0,j = 0; j < info->width * info->height; i +=mode, j++)
00165 newImageData[j] =
00166 (unsigned char)(0.30 * info->imageData[i] +
00167 0.59 * info->imageData[i+1] +
00168 0.11 * info->imageData[i+2]);
00169
00170
00171
00172 free(info->imageData);
00173
00174
00175 info->pixelDepth = 8;
00176 info->type = 3;
00177
00178 info->imageData = newImageData;
00179 }
00180
00181
00182 int tgaGrabScreenSeries(char *filename, int xmin,int ymin, int xmax, int ymax) {
00183
00184 int w, h;
00185 unsigned char *imageData;
00186
00187
00188 w = xmax - xmin;
00189 h = ymax - ymin;
00190
00191
00192 imageData = (unsigned char *)malloc(sizeof(unsigned char) * w * h * 4);
00193
00194
00195 glReadPixels(xmin,ymin,xmax,ymax,GL_RGBA,GL_UNSIGNED_BYTE, (void *)imageData);
00196
00197
00198 return (tgaSaveSeries(filename,(short int)w,(short int)h,32,imageData));
00199 }
00200
00201
00202
00203
00204
00205 int tgaSave( char *filename,
00206 short int width,
00207 short int height,
00208 unsigned char pixelDepth,
00209 unsigned char *imageData) {
00210
00211 unsigned char cGarbage = 0, type,mode,aux;
00212 short int iGarbage = 0;
00213 int i;
00214 FILE *file;
00215
00216
00217 file = fopen(filename, "wb");
00218 if (file == NULL) {
00219 return(TGA_ERROR_FILE_OPEN);
00220 }
00221
00222
00223 mode = (unsigned char)(pixelDepth / 8);
00224 if ((pixelDepth == 24) || (pixelDepth == 32))
00225 type = 2;
00226 else
00227 type = 3;
00228
00229
00230 fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00231 fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00232
00233 fwrite(&type, sizeof(unsigned char), 1, file);
00234
00235 fwrite(&iGarbage, sizeof(short int), 1, file);
00236 fwrite(&iGarbage, sizeof(short int), 1, file);
00237 fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00238 fwrite(&iGarbage, sizeof(short int), 1, file);
00239 fwrite(&iGarbage, sizeof(short int), 1, file);
00240
00241 fwrite(&width, sizeof(short int), 1, file);
00242 fwrite(&height, sizeof(short int), 1, file);
00243 fwrite(&pixelDepth, sizeof(unsigned char), 1, file);
00244
00245 fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00246
00247
00248 if (mode >= 3)
00249 for (i=0; i < width * height * mode ; i+= mode) {
00250 aux = imageData[i];
00251 imageData[i] = imageData[i+2];
00252 imageData[i+2] = aux;
00253 }
00254
00255
00256 fwrite(imageData, sizeof(unsigned char),
00257 width * height * mode, file);
00258 fclose(file);
00259
00260
00261
00262 return(TGA_OK);
00263 }
00264
00265
00266 int tgaSaveSeries(char *filename,
00267 short int width,
00268 short int height,
00269 unsigned char pixelDepth,
00270 unsigned char *imageData) {
00271
00272 char *newFilename;
00273 int status;
00274
00275
00276
00277 newFilename = (char *)malloc(sizeof(char) * strlen(filename)+8);
00278
00279 sprintf(newFilename,"%s%d.tga",filename,savedImages);
00280
00281
00282 status = tgaSave(newFilename,width,height,pixelDepth,imageData);
00283
00284
00285 savedImages++;
00286 return(status);
00287 }
00288
00289
00290
00291 void tgaDestroy(tgaInfo *info) {
00292
00293 if (info != NULL) {
00294 free(info->imageData);
00295 free(info);
00296 }
00297 }
00298