/* * Copyright (C) 2005 Maarten de Boer * * 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 #include } 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); }