- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

jpeg.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28
36 #ifndef __INCLUDE_MIST_JPEG__
37 #define __INCLUDE_MIST_JPEG__
38
39
40 #ifndef __INCLUDE_MIST_H__
41 #include "../mist.h"
42 #endif
43
44 // カラー画像の設定を読み込む
45 #ifndef __INCLUDE_MIST_COLOR_H__
46 #include "../config/color.h"
47 #endif
48
49 #ifndef __INCLUDE_MIST_LIMITS__
50 #include "../limits.h"
51 #endif
52
53
54 #include <iostream>
55 #include <string>
56
57
58 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
59
60 #define XMD_H
61 #define HAVE_INT32 // JPEG用INT32型を持っている宣言
62 #define HAVE_BOOLEAN // JPEG用boolean型を持っている宣言
63
64 #endif
65
66 extern "C"
67 {
68 #include <jpeglib.h>
69 }
70
71
72 // mist名前空間の始まり
73 _MIST_BEGIN
74
75
76 namespace __jpeg_controller__
77 {
78 template < class T, class Allocator >
79 struct jpeg_controller
80 {
81 typedef _pixel_converter_< T > pixel_converter;
82 typedef typename pixel_converter::color_type color_type;
83
84 static bool read( array2< T, Allocator > &image, const std::string &filename )
85 {
86 FILE *fin; // 読み書き用ファイルポインター
87 fin = fopen( filename.c_str( ), "rb" );
88 if( fin == NULL ) return( false );
89
90 JDIMENSION i, j;
91 JSAMPROW bitmap[1]; // ビットマップデータ配列へのポインター
92 jpeg_decompress_struct dinfo; // JPEG解凍情報構造体
93 jpeg_error_mgr jerr; // JPEGエラー処理用構造体
94 int scanlen; // ビットマップ１行のバイト数
95
96 dinfo.err = jpeg_std_error( &jerr );
97 jpeg_create_decompress( &dinfo );
98
99 //jpeg_stdio_src(&dinfo, fin, 0);
100 jpeg_stdio_src( &dinfo, fin );
101
102 int n = jpeg_read_header( &dinfo, true );
103 if( n < 1 )
104 {
105 jpeg_destroy_decompress( &dinfo );
106 return(false);
107 }
108
109 jpeg_start_decompress( &dinfo );
110 scanlen = dinfo.output_width * dinfo.output_components;
111
112 image.resize( dinfo.output_width, dinfo.output_height );
113
114 JSAMPLE *buffer = new JSAMPLE[ scanlen ];
115 for( j = 0 ; j < dinfo.output_height ; j++ )
116 {
117 bitmap[0] = &buffer[0];
118 if( dinfo.output_scanline < dinfo.output_height ) jpeg_read_scanlines( &dinfo, bitmap, 1 );
119 for( i = 0 ; i < dinfo.output_width ; i++ )
120 {
121 switch( dinfo.output_components )
122 {
123 case 1:
124 image( i, j ) = pixel_converter::convert_to( buffer[ i ], buffer[ i ], buffer[ i ] );
125 break;
126
127 case 3:
128 image( i, j ) = pixel_converter::convert_to( buffer[ i * 3 + 0 ], buffer[ i * 3 + 1 ], buffer[ i * 3 + 2 ] );
129 break;
130
131 default:
132 break;
133 }
134 }
135 }
136
137 jpeg_finish_decompress( &dinfo );
138
139 fclose( fin );
140 delete [] buffer;
141
142 jpeg_destroy_decompress( &dinfo );
143
144 return( true );
145 }
146
147 static bool write( const array2< T, Allocator > &image, const std::string &filename, int quality )
148 {
149 if( image.width( ) == 0 )
150 {
151 std::cerr << "Image width is zero!" << std::endl;
152 return( false );
153 }
154 else if( image.height( ) == 0 )
155 {
156 std::cerr << "Image height is zero!" << std::endl;
157 return( false );
158 }
159
160 FILE *fout; // 読み書き用ファイルポインター
161 fout = fopen( filename.c_str( ), "wb" );
162 if( fout == NULL ) return( false );
163
164 JDIMENSION i, j;
165 JDIMENSION w = static_cast< JDIMENSION >( image.width( ) ), h = static_cast< JDIMENSION >( image.height( ) );
166 JSAMPROW bitmap[1]; /* pointer to JSAMPLE row[s] */
167 jpeg_compress_struct cinfo; // JPEG解凍情報構造体
168 jpeg_error_mgr jerr; // JPEGエラー処理用構造体
169 //int linelen; // ビットマップ１行の正味バイト数
170 int scanlen = w * 3; // ビットマップ１行のバイト数
171
172 cinfo.err = jpeg_std_error( &jerr );
173 jpeg_create_compress( &cinfo );
174 //jpeg_stdio_dest(&cinfo, fout, 0);
175 jpeg_stdio_dest( &cinfo, fout );
176 cinfo.image_width = w;
177 cinfo.image_height = h;
178 cinfo.input_components = 3;
179 cinfo.in_color_space = JCS_RGB;
180 jpeg_set_defaults( &cinfo );
181 jpeg_set_quality( &cinfo, quality, true );
182 jpeg_start_compress( &cinfo, true );
183
184 JSAMPLE *buffer = new JSAMPLE[ w * h * 3 ];
185 JSAMPLE *p = buffer;
186
187 for( j = 0 ; j < h ; j++ )
188 {
189 for( i = 0 ; i < w ; i++ )
190 {
191 color_type c = limits_0_255( pixel_converter::convert_from( image( i, j ) ) );
192 *p++ = static_cast< JSAMPLE >( c.r );
193 *p++ = static_cast< JSAMPLE >( c.g );
194 *p++ = static_cast< JSAMPLE >( c.b );
195 }
196 }
197
198 while( cinfo.next_scanline < cinfo.image_height )
199 {
200 bitmap[0] = &buffer[ cinfo.next_scanline * scanlen ];
201 jpeg_write_scanlines( &cinfo, bitmap, 1 );
202 }
203
204 jpeg_finish_compress( &cinfo );
205
206 fclose( fout );
207 delete [] buffer;
208
209 jpeg_destroy_compress( &cinfo );
210
211 return( true );
212 }
213 };
214 }
215
216
219
231
232
243 template < class T, class Allocator >
244 bool read_jpeg( array2< T, Allocator > &image, const std::string &filename )
245 {
246 return( __jpeg_controller__::jpeg_controller< T, Allocator >::read( image, filename ) );
247 }
248
249
260 template < class T, class Allocator >
261 bool read_jpeg( array2< T, Allocator > &image, const std::wstring &filename )
262 {
263 return( read_jpeg( image, wstr2str( filename ) ) );
264 }
265
266
278 template < class T, class Allocator >
279 bool write_jpeg( const array2< T, Allocator > &image, const std::string &filename, int quality = 100 )
280 {
281 return( __jpeg_controller__::jpeg_controller< T, Allocator >::write( image, filename, quality ) );
282 }
283
284
296 template < class T, class Allocator >
297 bool write_jpeg( const array2< T, Allocator > &image, const std::wstring &filename, int quality = 100 )
298 {
299 return( write_jpeg( image, wstr2str( filename ), quality ) );
300 }
301
302
304 // JPEG 画像入出力グループの終わり
305
307 // 画像入出力グループの終わり
308
309
310 // mist名前空間の終わり
311 _MIST_END
312
313
314 #endif // __INCLUDE_MIST_JPEG__
315