2 * psychlops_g_JPEG_bridge.cpp
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2009/04/22 by Kenchi HOSOKAWA
6 * (C) 2006- Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
17 #include "../../../core/ApplicationInterfaces/psychlops_code_exception.h"
18 #include "../../../core/graphic/psychlops_g_image.h"
19 #include "psychlops_g_JPEG_bridge.h"
23 namespace IMAGE_FORMATS {
26 JPEG_BRIDGE::JPEG_BRIDGE() {
29 JPEG_BRIDGE::~JPEG_BRIDGE() {
34 void JPEG_BRIDGE::load(const char *file_name, Image * target) {
35 open(file_name, "rb");
40 void JPEG_BRIDGE::save(const char *file_name, Image * target) {
42 open(file_name, "wb");
44 prepare_before_write();
48 void JPEG_BRIDGE::open(const char *file_name, const char *mode) {
50 if ((fp = fopen(file_name, mode)) == NULL)
51 throw Exception(typeid(*this), "FILE ACCESS ERROR", "Failed to open the requested file.");
54 void JPEG_BRIDGE::close() {
55 if(is_opened_) fclose(fp);
60 void JPEG_BRIDGE::check_before_read() {
61 cinfo.err = jpeg_std_error(&jerr);
63 jpeg_create_decompress(&cinfo);
64 jpeg_stdio_src(&cinfo, fp);
65 jpeg_read_header(&cinfo, TRUE);
67 cinfo.dct_method = JDCT_ISLOW;
68 cinfo.quantize_colors = FALSE;
69 cinfo.dither_mode = JDITHER_NONE;
70 cinfo.do_fancy_upsampling = TRUE;
72 jpeg_calc_output_dimensions(&cinfo);
75 void JPEG_BRIDGE::read(Image * target) {
76 size_t width = cinfo.output_width;
77 size_t height = cinfo.output_height;
78 Image::PixelComponentsCnt pix_component;
79 switch (cinfo.output_components) {
81 pix_component = Image::GRAY;
84 pix_component = Image::RGB;
87 pix_component = Image::RGBA;
90 pix_component = Image::RGB;
93 //int rec_outbuf_height;
95 target->set(width, height, pix_component);
96 readTargetMemoryAlignment(target);
97 // for(unsigned int i=0; i<height; i++) row_pointers[i] = target_bitmap_ub_ + (height-i-1)*(target_bytes_per_line_);
98 size_t buf_w = sizeof(char)*width*cinfo.out_color_components;
99 char *iobuffer = (char *) (*cinfo.mem->alloc_small)((j_common_ptr)&cinfo, JPOOL_IMAGE, buf_w);
100 JSAMPROW pixrow = (JSAMPROW) iobuffer;
101 JSAMPARRAY samp_buf = &pixrow;
104 jpeg_start_decompress(&cinfo);
107 while (cinfo.output_scanline < cinfo.output_height) {
108 l_num = jpeg_read_scanlines(&cinfo, samp_buf, 1);
109 memcpy(target_bitmap_ub_+(height-l-1)*(target_bytes_per_line_), iobuffer, target_bytes_per_line_);
112 jpeg_finish_decompress(&cinfo);
113 jpeg_destroy_decompress(&cinfo);
119 void JPEG_BRIDGE::prepare_before_write() {
122 void JPEG_BRIDGE::write(Image * target) {
123 unsigned int width = (unsigned int)target->getWidth();
124 unsigned int height = (unsigned int)target->getHeight();
126 switch (pix_components_) {
137 unsigned int bit_depth;
138 switch(pix_precision_) {
140 throw Exception(typeid(*this), "FILE FORMAT ERROR", "The requested data is not able to be put as a PNG file.");