imagecapture.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:5k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // imagecapture.cpp
  2. // 
  3. // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. #include <cstdio>
  10. #include <celutil/debug.h>
  11. #include "../celengine/gl.h"
  12. #include <celengine/celestia.h>
  13. #include "imagecapture.h"
  14. extern "C" {
  15. #ifdef _WIN32
  16. #include "jpeglib.h"
  17. #else
  18. #ifdef MACOSX
  19. #include "../celestia/Celestia.app.skel/Contents/Frameworks/Headers/jpeglib.h"
  20. #else
  21. #include <jpeglib.h>
  22. #endif
  23. #endif
  24. }
  25. #ifdef MACOSX
  26. #include "../celestia/Celestia.app.skel/Contents/Frameworks/Headers/png.h"
  27. #else
  28. #include "png.h"
  29. #endif
  30. // Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng
  31. #ifndef png_jmpbuf
  32. #define png_jmpbuf(png_ptr) png_ptr->jmpbuf
  33. #endif
  34. // Define various expansion transformations for old versions of libpng
  35. #if PNG_LIBPNG_VER < 10004
  36. #define png_set_palette_to_rgb(p)  png_set_expand(p)
  37. #define png_set_gray_1_2_4_to_8(p) png_set_expand(p)
  38. #define png_set_tRNS_to_alpha(p)   png_set_expand(p)
  39. #endif
  40. using namespace std;
  41. bool CaptureGLBufferToJPEG(const string& filename,
  42.                            int x, int y,
  43.                            int width, int height)
  44. {
  45.     int rowStride = (width * 3 + 3) & ~0x3;
  46.     int imageSize = height * rowStride;
  47.     unsigned char* pixels = new unsigned char[imageSize];
  48.     glReadBuffer(GL_BACK);
  49.     glReadPixels(x, y, width, height,
  50.                  GL_RGB, GL_UNSIGNED_BYTE,
  51.                  pixels);
  52.     // TODO: Check for GL errors
  53.     FILE* out;
  54.     out = fopen(filename.c_str(), "wb");
  55.     if (out == NULL)
  56.     {
  57.         DPRINTF(0, "Can't open screen capture file '%s'n", filename.c_str());
  58.         delete[] pixels;
  59.         return false;
  60.     }
  61.     struct jpeg_compress_struct cinfo;
  62.     struct jpeg_error_mgr jerr;
  63.     JSAMPROW row[1];
  64.     cinfo.err = jpeg_std_error(&jerr);
  65.     jpeg_create_compress(&cinfo);
  66.     jpeg_stdio_dest(&cinfo, out);
  67.     cinfo.image_width = width;
  68.     cinfo.image_height = height;
  69.     cinfo.input_components = 3;
  70.     cinfo.in_color_space = JCS_RGB;
  71.     jpeg_set_defaults(&cinfo);
  72.     // jpeg_set_quality(&cinfo, quality, TRUE);
  73.     jpeg_start_compress(&cinfo, TRUE);
  74.     while (cinfo.next_scanline < cinfo.image_height)
  75.     {
  76.         row[0] = &pixels[rowStride * (cinfo.image_height - cinfo.next_scanline - 1)];
  77.         (void) jpeg_write_scanlines(&cinfo, row, 1);
  78.     }
  79.     jpeg_finish_compress(&cinfo);
  80.     fclose(out);
  81.     jpeg_destroy_compress(&cinfo);
  82.     delete[] pixels;
  83.     return true;
  84. }
  85. void PNGWriteData(png_structp png_ptr, png_bytep data, png_size_t length)
  86. {
  87.     FILE* fp = (FILE*) png_get_io_ptr(png_ptr);
  88.     fwrite((void*) data, 1, length, fp);
  89. }
  90.                            
  91. bool CaptureGLBufferToPNG(const string& filename,
  92.                            int x, int y,
  93.                            int width, int height)
  94. {
  95.     int rowStride = (width * 3 + 3) & ~0x3;
  96.     int imageSize = height * rowStride;
  97.     unsigned char* pixels = new unsigned char[imageSize];
  98.     glReadBuffer(GL_BACK);
  99.     glReadPixels(x, y, width, height,
  100.                  GL_RGB, GL_UNSIGNED_BYTE,
  101.                  pixels);
  102.     // TODO: Check for GL errors
  103.     FILE* out;
  104.     out = fopen(filename.c_str(), "wb");
  105.     if (out == NULL)
  106.     {
  107.         DPRINTF(0, "Can't open screen capture file '%s'n", filename.c_str());
  108.         delete[] pixels;
  109.         return false;
  110.     }
  111.     png_bytep* row_pointers = new png_bytep[height];
  112.     for (int i = 0; i < height; i++)
  113.         row_pointers[i] = (png_bytep) &pixels[rowStride * (height - i - 1)];
  114.     png_structp png_ptr;
  115.     png_infop info_ptr;
  116.     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
  117.                                       NULL, NULL, NULL);
  118.     if (png_ptr == NULL)
  119.     {
  120.         DPRINTF(0, "Screen capture: error allocating png_ptrn");
  121.         fclose(out);
  122.         delete[] pixels;
  123.         delete[] row_pointers;
  124.         return false;
  125.     }
  126.     info_ptr = png_create_info_struct(png_ptr);
  127.     if (info_ptr == NULL)
  128.     {
  129.         DPRINTF(0, "Screen capture: error allocating info_ptrn");
  130.         fclose(out);
  131.         delete[] pixels;
  132.         delete[] row_pointers;
  133.         png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  134.         return false;
  135.     }
  136.     if (setjmp(png_jmpbuf(png_ptr)))
  137.     {
  138.         DPRINTF(0, "Error writing PNG file '%s'n", filename.c_str());
  139.         fclose(out);
  140.         delete[] pixels;
  141.         delete[] row_pointers;
  142.         png_destroy_write_struct(&png_ptr, &info_ptr);
  143.         return false;
  144.     }
  145.     // png_init_io(png_ptr, out);
  146.     png_set_write_fn(png_ptr, (void*) out, PNGWriteData, NULL);
  147.     png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
  148.     png_set_IHDR(png_ptr, info_ptr,
  149.                  width, height,
  150.                  8,
  151.                  PNG_COLOR_TYPE_RGB,
  152.                  PNG_INTERLACE_NONE,
  153.                  PNG_COMPRESSION_TYPE_DEFAULT,
  154.                  PNG_FILTER_TYPE_DEFAULT);
  155.     png_write_info(png_ptr, info_ptr);
  156.     png_write_image(png_ptr, row_pointers);
  157.     png_write_end(png_ptr, info_ptr);
  158.     // Clean up everything . . .
  159.     png_destroy_write_struct(&png_ptr, &info_ptr);
  160.     delete[] row_pointers;
  161.     delete[] pixels;
  162.     fclose(out);
  163.     return true;
  164. }