예제 #1
0
	void jpeg_loader::read_image(const unsigned char * buffer, size_t len) {
		struct jpeg_decompress_struct cinfo;
		struct jpeg_error_mgr jerr;

		// Setup decompression structure
		cinfo.err = jpeg_std_error(&jerr);
		jpeg_create_decompress(&cinfo);
		my_set_source_mgr(&cinfo, buffer, len);

		// read info from header.
		int r = jpeg_read_header(&cinfo, TRUE);
		jpeg_start_decompress(&cinfo);

		// ..<snip>..
		// .. decompress the JPEG here as usual
		// ..<snip>..
		height_ = cinfo.output_height;
		width_ = cinfo.output_width;
		output_components_ = cinfo.output_components;

		if (output_components_ != 1 &&
			output_components_ != 3 &&
			output_components_ != 4)
		{
			jpeg_destroy_decompress(&cinfo);
			std::ostringstream sout;
			sout << "jpeg_loader: Unsupported number of colors (" << output_components_ << ") in buffer ";
			throw image_load_error(sout.str());
		}

		std::vector<unsigned char*> rows;
		rows.resize(height_);

		// size the image buffer
		data.resize(height_*width_*output_components_);

		// setup pointers to each row
		for (unsigned long i = 0; i < rows.size(); ++i)
			rows[i] = &data[i*width_*output_components_];

		// read the data into the buffer
		while (cinfo.output_scanline < cinfo.output_height)
		{
			jpeg_read_scanlines(&cinfo, &rows[cinfo.output_scanline], 100);
		}

		jpeg_finish_decompress(&cinfo);
		jpeg_destroy_decompress(&cinfo);


		jpeg_destroy_decompress(&cinfo);
	}
예제 #2
0
    void png_loader::read_image( const char* filename )
    {
        ld_.reset(new LibpngData);
        if ( filename == NULL )
        {
            throw image_load_error("png_loader: invalid filename, it is NULL");
        }
        FILE *fp = fopen( filename, "rb" );
        if ( !fp )
        {
            throw image_load_error(std::string("png_loader: unable to open file ") + filename);
        }
        png_byte sig[8];
        if (fread( sig, 1, 8, fp ) != 8)
        {
            fclose( fp );
            throw image_load_error(std::string("png_loader: error reading file ") + filename);
        }
        if ( png_sig_cmp( sig, 0, 8 ) != 0 )
        {
            fclose( fp );
            throw image_load_error(std::string("png_loader: format error in file ") + filename);
        }
        ld_->png_ptr_ = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
        if ( ld_->png_ptr_ == NULL )
        {
            fclose( fp );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
        ld_->info_ptr_ = png_create_info_struct( ld_->png_ptr_ );
        if ( ld_->info_ptr_ == NULL )
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), ( png_infopp )NULL, ( png_infopp )NULL );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
        ld_->end_info_ = png_create_info_struct( ld_->png_ptr_ );
        if ( ld_->end_info_ == NULL )
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), ( png_infopp )NULL );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
        png_init_io( ld_->png_ptr_, fp );
        png_set_sig_bytes( ld_->png_ptr_, 8 );
        // flags force one byte per channel output
        png_read_png( ld_->png_ptr_, ld_->info_ptr_, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING, NULL );
        height_ = png_get_image_height( ld_->png_ptr_, ld_->info_ptr_ );
        width_ = png_get_image_width( ld_->png_ptr_, ld_->info_ptr_ );
        bit_depth_ = png_get_bit_depth( ld_->png_ptr_, ld_->info_ptr_ );
        color_type_ = png_get_color_type( ld_->png_ptr_, ld_-> info_ptr_ );

        if (color_type_ != PNG_COLOR_TYPE_GRAY && 
            color_type_ != PNG_COLOR_TYPE_RGB && 
            color_type_ != PNG_COLOR_TYPE_RGB_ALPHA )
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) );
            throw image_load_error(std::string("png_loader: unsupported color type in file ") + filename);
        }

        ld_->row_pointers_ = png_get_rows( ld_->png_ptr_, ld_->info_ptr_ );
        // FIXME: the following call makes libpng crash. Why?
        //png_read_end( ld_->png_ptr_, ld_->end_info_ );
        fclose( fp );
        if ( ld_->row_pointers_ == NULL )
        {
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
    }
예제 #3
0
    void jpeg_loader::read_image( const char* filename )
    {
        if ( filename == NULL )
        {
            throw image_load_error("jpeg_loader: invalid filename, it is NULL");
        }
        FILE *fp = fopen( filename, "rb" );
        if ( !fp )
        {
            throw image_load_error(std::string("jpeg_loader: unable to open file ") + filename);
        }

        jpeg_decompress_struct cinfo;
        jpeg_loader_error_mgr jerr;

        cinfo.err = jpeg_std_error(&jerr.pub);

        jerr.pub.error_exit = jpeg_loader_error_exit;

        /* Establish the setjmp return context for my_error_exit to use. */
        if (setjmp(jerr.setjmp_buffer)) 
        {
            /* If we get here, the JPEG code has signaled an error.
             * We need to clean up the JPEG object, close the input file, and return.
             */
            jpeg_destroy_decompress(&cinfo);
            fclose(fp);
            throw image_load_error(std::string("jpeg_loader: error while reading ") + filename);
        }


        jpeg_create_decompress(&cinfo);

        jpeg_stdio_src(&cinfo, fp);

        jpeg_read_header(&cinfo, TRUE);

        jpeg_start_decompress(&cinfo);

        height_ = cinfo.output_height;
        width_ = cinfo.output_width;
        output_components_ = cinfo.output_components;

        if (output_components_ != 1 && 
            output_components_ != 3)
        {
            fclose( fp );
            jpeg_destroy_decompress(&cinfo);
            std::ostringstream sout;
            sout << "jpeg_loader: Unsupported number of colors (" << output_components_ << ") in file " << filename;
            throw image_load_error(sout.str());
        }

        std::vector<unsigned char*> rows;
        rows.resize(height_);

        // size the image buffer
        data.resize(height_*width_*output_components_);

        // setup pointers to each row
        for (unsigned long i = 0; i < rows.size(); ++i)
            rows[i] = &data[i*width_*output_components_];

        // read the data into the buffer
        while (cinfo.output_scanline < cinfo.output_height)
        {
            jpeg_read_scanlines(&cinfo, &rows[cinfo.output_scanline], 100);
        }

        jpeg_finish_decompress(&cinfo);
        jpeg_destroy_decompress(&cinfo);

        fclose( fp );
    }
예제 #4
0
    void png_loader::read_image( const char* filename )
    {
        ld_.reset(new LibpngData);
        if ( filename == NULL )
        {
            throw image_load_error("png_loader: invalid filename, it is NULL");
        }
        FILE *fp = fopen( filename, "rb" );
        if ( !fp )
        {
            throw image_load_error(std::string("png_loader: unable to open file ") + filename);
        }
        png_byte sig[8];
        if (fread( sig, 1, 8, fp ) != 8)
        {
            fclose( fp );
            throw image_load_error(std::string("png_loader: error reading file ") + filename);
        }
        if ( png_sig_cmp( sig, 0, 8 ) != 0 )
        {
            fclose( fp );
            throw image_load_error(std::string("png_loader: format error in file ") + filename);
        }
        ld_->png_ptr_ = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, &png_loader_user_error_fn_silent, &png_loader_user_warning_fn_silent );
        if ( ld_->png_ptr_ == NULL )
        {
            fclose( fp );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
        ld_->info_ptr_ = png_create_info_struct( ld_->png_ptr_ );
        if ( ld_->info_ptr_ == NULL )
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), ( png_infopp )NULL, ( png_infopp )NULL );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
        ld_->end_info_ = png_create_info_struct( ld_->png_ptr_ );
        if ( ld_->end_info_ == NULL )
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), ( png_infopp )NULL );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }

        if (setjmp(png_jmpbuf(ld_->png_ptr_)))
        {
            // If we get here, we had a problem writing the file 
            fclose(fp);
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }

        png_set_palette_to_rgb(ld_->png_ptr_);

        png_init_io( ld_->png_ptr_, fp );
        png_set_sig_bytes( ld_->png_ptr_, 8 );
        // flags force one byte per channel output
        byte_orderer bo;
        int png_transforms = PNG_TRANSFORM_PACKING;
        if (bo.host_is_little_endian())
            png_transforms |= PNG_TRANSFORM_SWAP_ENDIAN;
        png_read_png( ld_->png_ptr_, ld_->info_ptr_, png_transforms, NULL );
        height_ = png_get_image_height( ld_->png_ptr_, ld_->info_ptr_ );
        width_ = png_get_image_width( ld_->png_ptr_, ld_->info_ptr_ );
        bit_depth_ = png_get_bit_depth( ld_->png_ptr_, ld_->info_ptr_ );
        color_type_ = png_get_color_type( ld_->png_ptr_, ld_-> info_ptr_ );


        if (color_type_ != PNG_COLOR_TYPE_GRAY && 
            color_type_ != PNG_COLOR_TYPE_RGB && 
            color_type_ != PNG_COLOR_TYPE_RGB_ALPHA )
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) );
            throw image_load_error(std::string("png_loader: unsupported color type in file ") + filename);
        }

        if (bit_depth_ != 8 && bit_depth_ != 16)
        {
            fclose( fp );
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) );
            throw image_load_error("png_loader: unsupported bit depth of " + cast_to_string(bit_depth_) + " in file " + std::string(filename));
        }

        ld_->row_pointers_ = png_get_rows( ld_->png_ptr_, ld_->info_ptr_ );

        fclose( fp );
        if ( ld_->row_pointers_ == NULL )
        {
            png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) );
            throw image_load_error(std::string("png_loader: parse error in file ") + filename);
        }
    }