Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2012
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.25 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement