This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Feb 22nd, 2012  |  syntax: C++  |  size: 5.25 KB  |  views: 34  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // PngReader
  2. class PngReader {
  3. private:
  4.         FILE* file;
  5.  
  6.         png_structp pngReadStruct;
  7.         png_infop pngInfoStruct;
  8.  
  9.         void* data;
  10.         png_bytep *dataRows;
  11.  
  12.         // Processing routines
  13.         int sigCheck();
  14.         bool setUp();
  15.         void setColors();
  16.         void rowsToData(bool bottomUp = false);
  17.  
  18. public:
  19.  
  20.         int error;
  21.  
  22.         uint32_t width, height;
  23.         uint32_t bitDepth;
  24.         uint32_t channels, colorType;
  25.  
  26.         // Constructors, destructor
  27.         PngReader();
  28.         PngReader(std::string filename);
  29.         virtual ~PngReader();
  30.  
  31.         // Open, close
  32.         void open (std::string filename);
  33.         void close ();
  34.  
  35.         void* read();
  36.  
  37.         Texture generateTexture();
  38.  
  39. };
  40.  
  41. /************************************************
  42.  *   Constructors, destructor                   *
  43.  ************************************************/
  44. PngReader::PngReader() {
  45.         file = NULL;
  46.         error = 0;
  47.         pngReadStruct = NULL;
  48.         pngInfoStruct = NULL;
  49. }
  50.  
  51. PngReader::PngReader(std::string filename) {
  52.         error = 0;
  53.         pngReadStruct = NULL;
  54.         pngInfoStruct = NULL;
  55.  
  56.         open(filename);
  57. }
  58.  
  59. PngReader::~PngReader() {
  60.         close();
  61. }
  62.  
  63.  
  64. /************************************************
  65.  *   Processing                                 *
  66.  ************************************************/
  67. int PngReader::sigCheck() {
  68.  
  69.         unsigned char sig[8];
  70.  
  71.         if (error != 0 || file == NULL) return false;
  72.         fread(sig, sizeof(char), 8, file);
  73.         return png_sig_cmp(sig, 0, 8);
  74. }
  75.  
  76.  
  77. bool PngReader::setUp()
  78. {
  79.         // Create the necessary structures
  80.         pngReadStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  81.         if (!pngReadStruct) {
  82.                 Error ("[PngReader] Failed to create read structure.");
  83.                 error = 3;
  84.                 return false;
  85.         }
  86.  
  87.         pngInfoStruct = png_create_info_struct(pngReadStruct);
  88.         if (!pngInfoStruct) {
  89.                 Error ("[PngReader] Failed to create info structure.");
  90.                 png_destroy_read_struct(&pngReadStruct, NULL, NULL);
  91.                 error = 4; return false;
  92.         }
  93.  
  94.         // Set up reading
  95.         png_init_io(pngReadStruct, file);
  96.         png_set_sig_bytes(pngReadStruct, 8);
  97.  
  98.         // Read header
  99.         png_read_info(pngReadStruct, pngInfoStruct);
  100.         width = png_get_image_width(pngReadStruct, pngInfoStruct);
  101.         height = png_get_image_height(pngReadStruct, pngInfoStruct);
  102.         bitDepth = png_get_bit_depth(pngReadStruct, pngInfoStruct);
  103.         channels = png_get_channels(pngReadStruct, pngInfoStruct);
  104.         colorType = png_get_color_type(pngReadStruct, pngInfoStruct);
  105.  
  106.         png_set_interlace_handling(pngReadStruct);
  107.         png_read_update_info(pngReadStruct, pngInfoStruct);
  108.  
  109.         return true;
  110. }
  111.  
  112. void PngReader::setColors()
  113. {
  114.         // We will get image in rgb format
  115.         switch (colorType)
  116.         {
  117.                 case PNG_COLOR_TYPE_GRAY:
  118.                         png_set_expand_gray_1_2_4_to_8(pngReadStruct);
  119.                         bitDepth = 8;
  120.                         break;
  121.  
  122.                 case PNG_COLOR_TYPE_PALETTE:
  123.                         png_set_palette_to_rgb(pngReadStruct);
  124.                         channels = 3;
  125.                         break;
  126.         }
  127.  
  128.         if (png_get_valid(pngReadStruct, pngInfoStruct, PNG_INFO_tRNS))
  129.         {
  130.                 png_set_tRNS_to_alpha(pngReadStruct);
  131.                 ++channels;
  132.         }
  133.  
  134.         if (bitDepth == 16) png_set_strip_16(pngReadStruct);
  135. }
  136.  
  137. /************************************************
  138.  *   Open and close                             *
  139.  ************************************************/
  140. void PngReader::open(string filename) {
  141.  
  142.         // Open file
  143.         file = fopen(filename.c_str(), "rb");
  144.         if (!file) {
  145.                 Error("[PngReader] Cannot open file %s", filename.c_str());
  146.                 error = 1; return;
  147.         }
  148.  
  149.         // Check signature
  150.         if (sigCheck()) {
  151.                 Error("[PngReader] File %s is not png.", filename.c_str());
  152.                 error = 2; return;
  153.         }
  154.  
  155.         // Set up the image
  156.         if (!setUp()) return;
  157.         setColors();
  158. }
  159.  
  160.  
  161. void PngReader::close() {
  162.         if (pngInfoStruct) {
  163.                 png_destroy_info_struct(pngReadStruct, &pngInfoStruct);
  164.                 pngInfoStruct = NULL;
  165.         }
  166.  
  167.         if (pngReadStruct) {
  168.                 png_destroy_read_struct(&pngReadStruct, NULL, NULL);
  169.                 pngReadStruct = NULL;
  170.         }
  171.  
  172.         if (data) {
  173.                 free(data); data = NULL;
  174.         }
  175.  
  176.         if (file) {
  177.                 fclose(file); file = NULL;
  178.         }
  179. }
  180.  
  181.  
  182. /************************************************
  183.  *   Reading                                    *
  184.  ************************************************/
  185. void PngReader::rowsToData(bool bottomUp)
  186. {
  187.         data = malloc(width * height * bitDepth * channels / 8);
  188.  
  189.         for (uint32_t i=0; i<height; i++) {
  190.                 if (bottomUp) {
  191.                         memcpy((void*) ((size_t)data + (width * i)), dataRows[height - i - 1],
  192.                                         width * bitDepth * channels / 8);
  193.                         free (dataRows[height - i - 1]);
  194.                 }
  195.  
  196.                 else {
  197.                         memcpy((void*) ((size_t)data + (width * i)), dataRows[i],
  198.                                         width * bitDepth * channels / 8);
  199.  
  200.                         free (dataRows[i]);
  201.                 }
  202.         }
  203.  
  204.         free(dataRows);
  205. }
  206.  
  207. void* PngReader::read()
  208. {
  209.         // Make sure we don't have an error
  210.         if (!file || error) return NULL;
  211.  
  212.         // Allocate rows
  213.         dataRows = (png_bytep*) malloc(sizeof(png_bytep) * height);
  214.         for (uint32_t i=0; i<height; i++)
  215.                 dataRows[i] = (png_bytep) malloc(png_get_rowbytes(pngReadStruct, pngInfoStruct));
  216.  
  217.         // Read rows
  218.         png_read_image(pngReadStruct, dataRows);
  219.         rowsToData();
  220.  
  221.         return data;
  222. }
  223.  
  224. /************************************************
  225.  *   Texture generate                           *
  226.  ************************************************/
  227. Texture PngReader::generateTexture()
  228. {
  229.         if (this->error) return Texture();
  230.  
  231.         Texture t;
  232.         if (channels == 3)
  233.                 t.loadData(width, height, channels, GL_RGB, data);
  234.         else if (channels == 4)
  235.                 t.loadData(width, height, channels, GL_RGBA, data);
  236.  
  237.         return t;
  238. }
clone this paste RAW Paste Data