Utils.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2005 Dave Griffiths
00002 //
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 
00017 #include <tiffio.h> 
00018 extern "C"
00019 {
00020 #include <jpeglib.h>    
00021 }
00022 #include "Utils.h"
00023 #include <iostream>
00024 #include <fstream>
00025 
00026 using namespace std;
00027 
00028 GLubyte *GetScreenBuffer(int x, int y, int &width, int &height, int super)
00029 {
00030     // get the raw image
00031     GLubyte *image = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3);
00032     // OpenGL's default 4 byte pack alignment would leave extra bytes at the
00033     // end of each image row so that each full row contained a number of bytes
00034     // divisible by 4.  Ie, an RGB row with 3 pixels and 8-bit componets would
00035     // be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist
00036     // just to pad the row out to 12 bytes (12 is divisible by 4). To make sure
00037     // the rows are packed as tight as possible (no row padding), set the pack
00038     // alignment to 1. 
00039     glPixelStorei(GL_PACK_ALIGNMENT, 1);
00040     glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
00041     
00042     if (super==1) return image;
00043         
00044     // supersample the image
00045     int newwidth=width/super;
00046     int newheight=height/super;
00047 
00048     GLubyte *image2 = (GLubyte *) malloc(newwidth * newheight * sizeof(GLubyte) * 3);
00049 
00050     for (int yy=0; yy<newheight; yy++)
00051     {
00052         for (int xx=0; xx<newwidth; xx++)
00053         {
00054             int sx=xx*super;
00055             int sy=yy*super;
00056             int i=(yy*newwidth+xx)*3;
00057 
00058             int a=(sy*width+sx)*3;
00059             int b=(sy*width+(sx+1))*3;
00060             int c=((sy+1)*width+(sx+1))*3;
00061             int d=((sy+1)*width+sx)*3;
00062 
00063             image2[i]=(image[a]+image[b]+image[c]+image[d])/4;
00064             image2[i+1]=(image[a+1]+image[b+1]+image[c+1]+image[d+1])/4;
00065             image2[i+2]=(image[a+2]+image[b+2]+image[c+2]+image[d+2])/4;
00066         }
00067     }
00068     
00069     width=newwidth;
00070     height=newheight;
00071 
00072     free(image);    
00073     return image2;
00074 }
00075 
00076 int WriteTiff(const char *filename, const char *description, int x, int y, int width, int height, int compression, int super)
00077 {
00078     TIFF *file;
00079     GLubyte *image, *p;
00080     int i;
00081 
00082     file = TIFFOpen(filename, "w");
00083     if (file == NULL) 
00084     {
00085         return 1;
00086     }
00087     
00088     image = GetScreenBuffer(x, y, width, height, super);
00089     
00090     TIFFSetField(file, TIFFTAG_IMAGEWIDTH, (uint32) width);
00091     TIFFSetField(file, TIFFTAG_IMAGELENGTH, (uint32) height);
00092     TIFFSetField(file, TIFFTAG_BITSPERSAMPLE, 8);
00093     TIFFSetField(file, TIFFTAG_COMPRESSION, compression);
00094     TIFFSetField(file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
00095     TIFFSetField(file, TIFFTAG_SAMPLESPERPIXEL, 3);
00096     TIFFSetField(file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00097     TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1);
00098     TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description);
00099     p = image;
00100     for (i = height - 1; i >= 0; i--) 
00101     {
00102         if (TIFFWriteScanline(file, p, i, 0) < 0) 
00103         {
00104             free(image);
00105             TIFFClose(file);
00106             return 1;
00107         }
00108         p += width * sizeof(GLubyte) * 3;
00109     }
00110     TIFFClose(file);
00111     free(image);
00112     return 0;
00113 }   
00114 
00115 int WriteJPG(const char *filename, const char *description, int x, int y, int width, int height, int quality, int super)
00116 {
00117     GLubyte *image = GetScreenBuffer(x, y, width, height, super);
00118 
00119     struct jpeg_compress_struct cinfo;
00120     struct jpeg_error_mgr jerr;
00121  
00122     FILE * outfile;     
00123     JSAMPROW row_pointer[1];
00124     int row_stride;     
00125 
00126     cinfo.err = jpeg_std_error(&jerr);
00127     jpeg_create_compress(&cinfo);
00128  
00129     if ((outfile = fopen(filename, "wb")) == NULL) 
00130     {
00131         return 1;
00132     }
00133     
00134     jpeg_stdio_dest(&cinfo, outfile);
00135     
00136     cinfo.image_width = width; 
00137     cinfo.image_height = height;
00138     cinfo.input_components = 3; 
00139     cinfo.in_color_space = JCS_RGB;
00140  
00141     jpeg_set_defaults(&cinfo);
00142     jpeg_set_quality(&cinfo, quality, TRUE);
00143     jpeg_start_compress(&cinfo, TRUE);
00144 
00145     row_stride = width * 3; 
00146 
00147     while (cinfo.next_scanline < cinfo.image_height) 
00148     {
00149         row_pointer[0] = & image[(cinfo.image_height-cinfo.next_scanline) * row_stride];
00150         (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
00151     }
00152 
00153     jpeg_finish_compress(&cinfo);
00154     fclose(outfile);
00155 
00156     jpeg_destroy_compress(&cinfo);
00157     free(image);
00158     
00159     return 0;
00160 }   
00161 
00162 int WritePPM(const char *filename, const char *description, int x, int y, int width, int height, int compression, int super)
00163 {
00164     FILE* file = fopen(filename,"w");
00165     if (file == NULL) 
00166     {
00167         return 1;
00168     }
00169     
00170     GLubyte *image = GetScreenBuffer(x, y, width, height, super);
00171     char buf[256];
00172     sprintf(buf,"P6\n%d\n%d\n255\n",width,height);
00173     fwrite(buf,strlen(buf)*sizeof(char),1,file);
00174     for (int y=height-1; y>-1; y--)
00175     {
00176         fwrite(image+y*width*3,width*3,1,file);
00177     }
00178     fclose(file);
00179     free(image);
00180     
00181     return 0;
00182 }   

Generated on Tue Sep 4 23:22:18 2007 for The Fluxus Renderer (libfluxus) by  doxygen 1.5.1