OSDN Git Service

first
[psychlops/cpp.git] / psychlops / extension / FileFormat / JPEG / psychlops_g_JPEG_bridge.cpp
1 /*
2  *  psychlops_g_JPEG_bridge.cpp
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2009/04/22 by Kenchi HOSOKAWA
6  *  (C) 2006- Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 extern "C" {
13 #include "jpeglib.h"
14 }
15
16
17 #include "../../../core/ApplicationInterfaces/psychlops_code_exception.h"
18 #include "../../../core/graphic/psychlops_g_image.h"
19 #include "psychlops_g_JPEG_bridge.h"
20
21
22 namespace Psychlops {
23 namespace IMAGE_FORMATS {
24
25
26         JPEG_BRIDGE::JPEG_BRIDGE() {
27                 is_opened_ = false;
28         }
29         JPEG_BRIDGE::~JPEG_BRIDGE() {
30                 close();
31         }
32
33
34         void JPEG_BRIDGE::load(const char *file_name, Image * target) {
35                 open(file_name, "rb");
36
37                 check_before_read();
38                 read(target);
39         }
40         void JPEG_BRIDGE::save(const char *file_name, Image * target) {
41 /*
42                 open(file_name, "wb");
43
44                 prepare_before_write();
45                 write(target);
46 */
47         }
48         void JPEG_BRIDGE::open(const char *file_name, const char *mode) {
49                 if(!is_opened_)
50                         if ((fp = fopen(file_name, mode)) == NULL)
51                                         throw Exception(typeid(*this), "FILE ACCESS ERROR", "Failed to open the requested file.");
52                 is_opened_ = true;
53         }
54         void JPEG_BRIDGE::close() {
55                 if(is_opened_) fclose(fp);
56                 is_opened_ = false;
57         }
58
59
60         void JPEG_BRIDGE::check_before_read() {
61                 cinfo.err = jpeg_std_error(&jerr);
62
63                 jpeg_create_decompress(&cinfo);
64                 jpeg_stdio_src(&cinfo, fp);
65                 jpeg_read_header(&cinfo, TRUE);
66
67                 cinfo.dct_method = JDCT_ISLOW;
68                 cinfo.quantize_colors = FALSE;
69                 cinfo.dither_mode = JDITHER_NONE;
70                 cinfo.do_fancy_upsampling = TRUE;
71
72                 jpeg_calc_output_dimensions(&cinfo);
73 }
74
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) {
80                         case 1:
81                                 pix_component = Image::GRAY;
82                                 break;
83                         case 3:
84                                 pix_component = Image::RGB;
85                                 break;
86                         case 4:
87                                 pix_component = Image::RGBA;
88                                 break;
89                         default:
90                                 pix_component = Image::RGB;
91                                 break;
92                 }
93                 //int rec_outbuf_height;
94
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;
102
103
104                 jpeg_start_decompress(&cinfo);
105                 int l = 0;
106                 JDIMENSION l_num;
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_);
110                         l++;
111                 }
112                 jpeg_finish_decompress(&cinfo);
113                 jpeg_destroy_decompress(&cinfo);
114         }
115
116
117
118
119         void JPEG_BRIDGE::prepare_before_write() {
120         }
121
122         void JPEG_BRIDGE::write(Image * target) {
123                 unsigned int width = (unsigned int)target->getWidth();
124                 unsigned int height = (unsigned int)target->getHeight();
125
126                 switch (pix_components_) {
127                         case Image::GRAY:
128                                 break;
129                         case Image::RGB:
130                                 break;
131                         case Image::RGBA:
132                                 break;
133                         default:
134                                 break;
135                 }
136
137                 unsigned int bit_depth;
138                 switch(pix_precision_) {
139                         case Image::FLOAT:
140                                 throw Exception(typeid(*this), "FILE FORMAT ERROR", "The requested data is not able to be put as a PNG file.");
141                                 break;
142                         case Image::BYTE:
143                                 bit_depth = 8;
144                                 break;
145                         default:
146                                 bit_depth = 8;
147                                 break;
148                 }
149         }
150
151
152 }
153 }