Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

imagecapture.cpp

Go to the documentation of this file.
00001 // imagecapture.cpp
00002 // 
00003 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <cstdio>
00011 #include <celutil/debug.h>
00012 #include "../celengine/gl.h"
00013 #include <celengine/celestia.h>
00014 #include "imagecapture.h"
00015 
00016 extern "C" {
00017 #ifdef _WIN32
00018 #include "jpeglib.h"
00019 #else
00020 #ifdef MACOSX
00021 #include "../celestia/Celestia.app.skel/Contents/Frameworks/Headers/jpeglib.h"
00022 #else
00023 #include <jpeglib.h>
00024 #endif
00025 #endif
00026 }
00027 
00028 #ifdef MACOSX
00029 #include "../celestia/Celestia.app.skel/Contents/Frameworks/Headers/png.h"
00030 #else
00031 #include "png.h"
00032 #endif
00033 
00034 // Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng
00035 #ifndef png_jmpbuf
00036 #define png_jmpbuf(png_ptr) png_ptr->jmpbuf
00037 #endif
00038 
00039 // Define various expansion transformations for old versions of libpng
00040 #if PNG_LIBPNG_VER < 10004
00041 #define png_set_palette_to_rgb(p)  png_set_expand(p)
00042 #define png_set_gray_1_2_4_to_8(p) png_set_expand(p)
00043 #define png_set_tRNS_to_alpha(p)   png_set_expand(p)
00044 #endif
00045 
00046 using namespace std;
00047 
00048 
00049 bool CaptureGLBufferToJPEG(const string& filename,
00050                            int x, int y,
00051                            int width, int height)
00052 {
00053     int rowStride = (width * 3 + 3) & ~0x3;
00054     int imageSize = height * rowStride;
00055     unsigned char* pixels = new unsigned char[imageSize];
00056 
00057     glReadBuffer(GL_BACK);
00058     glReadPixels(x, y, width, height,
00059                  GL_RGB, GL_UNSIGNED_BYTE,
00060                  pixels);
00061 
00062     // TODO: Check for GL errors
00063 
00064     FILE* out;
00065     out = fopen(filename.c_str(), "wb");
00066     if (out == NULL)
00067     {
00068         DPRINTF(0, "Can't open screen capture file '%s'\n", filename.c_str());
00069         delete[] pixels;
00070         return false;
00071     }
00072 
00073     struct jpeg_compress_struct cinfo;
00074 
00075     struct jpeg_error_mgr jerr;
00076     JSAMPROW row[1];
00077 
00078     cinfo.err = jpeg_std_error(&jerr);
00079     jpeg_create_compress(&cinfo);
00080 
00081     jpeg_stdio_dest(&cinfo, out);
00082 
00083     cinfo.image_width = width;
00084     cinfo.image_height = height;
00085     cinfo.input_components = 3;
00086     cinfo.in_color_space = JCS_RGB;
00087 
00088     jpeg_set_defaults(&cinfo);
00089 
00090     // jpeg_set_quality(&cinfo, quality, TRUE);
00091 
00092     jpeg_start_compress(&cinfo, TRUE);
00093 
00094     while (cinfo.next_scanline < cinfo.image_height)
00095     {
00096         row[0] = &pixels[rowStride * (cinfo.image_height - cinfo.next_scanline - 1)];
00097         (void) jpeg_write_scanlines(&cinfo, row, 1);
00098     }
00099 
00100     jpeg_finish_compress(&cinfo);
00101     fclose(out);
00102     jpeg_destroy_compress(&cinfo);
00103 
00104     delete[] pixels;
00105 
00106     return true;
00107 }
00108 
00109 
00110 void PNGWriteData(png_structp png_ptr, png_bytep data, png_size_t length)
00111 {
00112     FILE* fp = (FILE*) png_get_io_ptr(png_ptr);
00113     fwrite((void*) data, 1, length, fp);
00114 }
00115 
00116                            
00117 bool CaptureGLBufferToPNG(const string& filename,
00118                            int x, int y,
00119                            int width, int height)
00120 {
00121     int rowStride = (width * 3 + 3) & ~0x3;
00122     int imageSize = height * rowStride;
00123     unsigned char* pixels = new unsigned char[imageSize];
00124 
00125     glReadBuffer(GL_BACK);
00126     glReadPixels(x, y, width, height,
00127                  GL_RGB, GL_UNSIGNED_BYTE,
00128                  pixels);
00129 
00130     // TODO: Check for GL errors
00131 
00132     FILE* out;
00133     out = fopen(filename.c_str(), "wb");
00134     if (out == NULL)
00135     {
00136         DPRINTF(0, "Can't open screen capture file '%s'\n", filename.c_str());
00137         delete[] pixels;
00138         return false;
00139     }
00140 
00141     png_bytep* row_pointers = new png_bytep[height];
00142     for (int i = 0; i < height; i++)
00143         row_pointers[i] = (png_bytep) &pixels[rowStride * (height - i - 1)];
00144 
00145     png_structp png_ptr;
00146     png_infop info_ptr;
00147 
00148     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
00149                                       NULL, NULL, NULL);
00150 
00151     if (png_ptr == NULL)
00152     {
00153         DPRINTF(0, "Screen capture: error allocating png_ptr\n");
00154         fclose(out);
00155         delete[] pixels;
00156         delete[] row_pointers;
00157         return false;
00158     }
00159 
00160     info_ptr = png_create_info_struct(png_ptr);
00161     if (info_ptr == NULL)
00162     {
00163         DPRINTF(0, "Screen capture: error allocating info_ptr\n");
00164         fclose(out);
00165         delete[] pixels;
00166         delete[] row_pointers;
00167         png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
00168         return false;
00169     }
00170 
00171     if (setjmp(png_jmpbuf(png_ptr)))
00172     {
00173         DPRINTF(0, "Error writing PNG file '%s'\n", filename.c_str());
00174         fclose(out);
00175         delete[] pixels;
00176         delete[] row_pointers;
00177         png_destroy_write_struct(&png_ptr, &info_ptr);
00178         return false;
00179     }
00180 
00181     // png_init_io(png_ptr, out);
00182     png_set_write_fn(png_ptr, (void*) out, PNGWriteData, NULL);
00183 
00184     png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
00185     png_set_IHDR(png_ptr, info_ptr,
00186                  width, height,
00187                  8,
00188                  PNG_COLOR_TYPE_RGB,
00189                  PNG_INTERLACE_NONE,
00190                  PNG_COMPRESSION_TYPE_DEFAULT,
00191                  PNG_FILTER_TYPE_DEFAULT);
00192 
00193     png_write_info(png_ptr, info_ptr);
00194     png_write_image(png_ptr, row_pointers);
00195     png_write_end(png_ptr, info_ptr);
00196 
00197     // Clean up everything . . .
00198     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
00199     delete[] row_pointers;
00200     delete[] pixels;
00201     fclose(out);
00202 
00203     return true;
00204 }
00205 
00206 

Generated on Sat Jan 14 22:30:30 2006 for Celestia by  doxygen 1.4.1