Logo Search packages:      
Sourcecode: jigzo version File versions  Download package

Loader.cxx

/*
 *  Copyright (C) 2005-2008  Maarten de Boer <maarten@resorama.com>
 * 
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 *  02110-1301, USA.
 * 
 */

#include "Loader.hxx"

extern "C"
{
#include <png.h>
#include <jpeglib.h>
}

void JpgLoader::Load(const std::string& filename,RGB& target,int x,int y)
{
      FILE *infile = fopen(filename.c_str(), "rb");
      if (!infile)
            throw LoaderException(std::string("failed to open ")+filename);

      struct jpeg_decompress_struct cinfo;
      struct jpeg_error_mgr jerr;
      cinfo.err = jpeg_std_error(&jerr);
      jpeg_create_decompress(&cinfo);
      jpeg_stdio_src(&cinfo, infile);
      jpeg_read_header(&cinfo, TRUE);
      jpeg_start_decompress(&cinfo);

      width = cinfo.output_width;
      height = cinfo.output_height;

      unsigned char *line =
            (unsigned char *) malloc(width *
                                                             cinfo.output_components);
      int k = 0;
      while (cinfo.output_scanline < height) {
            unsigned char* ptr = target.Data() + (y+k)*target.Width()*3 + x*3;
            jpeg_read_scanlines(&cinfo, &line, 1);
            unsigned char *jpeg_ptr = line;
            for (unsigned int i = 0; i < width; i++) {
                  *ptr++ = *jpeg_ptr++;
                  *ptr++ = *jpeg_ptr++;
                  *ptr++ = *jpeg_ptr++;
            }
            k++;
      }
      free(line);
      jpeg_finish_decompress(&cinfo);
      jpeg_destroy_decompress(&cinfo);

      fclose(infile);
}

void JpgLoader::Load(const std::string& filename,RGBA& target,int x,int y)
{
      FILE *infile = fopen(filename.c_str(), "rb");
      if (!infile)
            throw LoaderException(std::string("failed to open ")+filename);

      struct jpeg_decompress_struct cinfo;
      struct jpeg_error_mgr jerr;
      cinfo.err = jpeg_std_error(&jerr);
      jpeg_create_decompress(&cinfo);
      jpeg_stdio_src(&cinfo, infile);
      jpeg_read_header(&cinfo, TRUE);
      jpeg_start_decompress(&cinfo);

      width = cinfo.output_width;
      height = cinfo.output_height;

      unsigned char *line =
            (unsigned char *) malloc(width *
                                                             cinfo.output_components);
      int k = 0;
      while (cinfo.output_scanline < height) {
            unsigned char* ptr = target.Data() + (y+k)*target.Width()*4 + x*4;
            jpeg_read_scanlines(&cinfo, &line, 1);
            unsigned char *jpeg_ptr = line;
            for (unsigned int i = 0; i < width; i++) {
                  *ptr++ = *jpeg_ptr++;
                  *ptr++ = *jpeg_ptr++;
                  *ptr++ = *jpeg_ptr++;
                  *ptr++ = 255;
            }
            k++;
      }
      free(line);
      jpeg_finish_decompress(&cinfo);
      jpeg_destroy_decompress(&cinfo);

      fclose(infile);
}

void JpgLoader::Merge(const std::string& filename,RGBA& target,int x,int y)
{
      FILE* infile = fopen(filename.c_str(), "rb");
      if (!infile)
            throw LoaderException(std::string("failed to open ")+filename);

      struct jpeg_decompress_struct cinfo;
      struct jpeg_error_mgr jerr;
      cinfo.err = jpeg_std_error(&jerr);
      jpeg_create_decompress(&cinfo);
      jpeg_stdio_src(&cinfo, infile);
      jpeg_read_header(&cinfo, TRUE);
      jpeg_start_decompress(&cinfo);

      unsigned char *line =
            (unsigned char *) malloc(cinfo.output_width *
                                                             cinfo.output_components);
      int k = 0;
      while (cinfo.output_scanline < cinfo.output_height) {
            unsigned char* ptr = target.Data() + (y+k)*target.Width()*4 + x*4;
            jpeg_read_scanlines(&cinfo, &line, 1);
            unsigned char *jpeg_ptr = line;
            for (unsigned int i = 0; i < cinfo.output_width; i++) {
                  if (ptr[0] == 255 &&
                              ptr[1] == 255 && ptr[2] == 255 && ptr[3] == 255) {
                        *ptr++ = *jpeg_ptr++;
                        *ptr++ = *jpeg_ptr++;
                        *ptr++ = *jpeg_ptr++;
                        ptr++;
                  } else {
                        ptr += 4;
                        jpeg_ptr += 3;
                  }
            }
            k++;
      }
      free(line);
      jpeg_finish_decompress(&cinfo);
      jpeg_destroy_decompress(&cinfo);

      fclose(infile);
}
void PngLoader::Load(const std::string& filename,RGBA& target)
{
      png_byte header[8];
      int number = 8;

      FILE *fp = fopen(filename.c_str(), "rb");
      if (!fp) {
            throw LoaderException(std::string("cannot open "+filename));
      }
      fread(header, 1, number, fp);
      int is_png = !png_sig_cmp(header, 0, number);
      if (!is_png) {
            fclose(fp);
            throw LoaderException(filename+" is not a png");
      }

      png_structp png_ptr = png_create_read_struct
                                                 (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
      if (!png_ptr)
      {
            fclose(fp);
            throw LoaderException("png_create_read_struct failed");
      }
      png_infop info_ptr = png_create_info_struct(png_ptr);
      if (!info_ptr) {
            png_destroy_read_struct(&png_ptr,
                                                            (png_infopp) NULL, (png_infopp) NULL);
            fclose(fp);
            throw LoaderException("png_create_info_struct failed");
      }

      png_infop end_info = png_create_info_struct(png_ptr);
      if (!end_info) {
            png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
            throw LoaderException("png_create_info_struct (end_info) failed");
      }
      if (setjmp(png_jmpbuf(png_ptr))) {
            png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
            fclose(fp);
            throw LoaderException("png_create_info_struct (end_info) failed");
      }
      png_init_io(png_ptr, fp);
      png_set_sig_bytes(png_ptr, number);
      png_uint_32 width, height;
      int bit_depth, color_type, interlace_type;
      png_read_info(png_ptr, info_ptr);
      png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
                               &color_type, &interlace_type, int_p_NULL, int_p_NULL);

      int row_bytes = png_get_rowbytes(png_ptr, info_ptr);

      png_bytep *row_pointers =
            (png_bytep *) png_malloc(png_ptr, height * sizeof(png_bytep));

      target.Alloc(width,height);

      png_bytep ptr = target.Data();
      for (unsigned int i = 0; i < height; i++) {
            row_pointers[i] = ptr;
            ptr += row_bytes;
      }
      png_read_image(png_ptr, row_pointers);
      png_read_end(png_ptr, NULL);
      png_free(png_ptr, row_pointers);
      png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
      fclose(fp);
}


Generated by  Doxygen 1.6.0   Back to index