00001 /*00002 Copyright 2005-2007 Adobe Systems Incorporated00003 00004 Use, modification and distribution are subject to the Boost Software License,00005 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at00006 http://www.boost.org/LICENSE_1_0.txt).00007
00008 See http://opensource.adobe.com/gil for most recent version including documentation.00009 */00010
00011 /*************************************************************************************************/00012
00013 #ifndef GIL_JPEG_IO_PRIVATE_H00014 #define GIL_JPEG_IO_PRIVATE_H00015
00021
00022 #include <stdio.h>00023 #include <boost/static_assert.hpp>00024 #include <vector>00025 #include "../../gil_all.hpp"00026 #include "io_error.hpp"00027 #include <jpeglib.h>00028
00029 namespace boost { namespace gil {
00030
00031 namespace detail {
00032
00033 // lbourdev: What is the advantage of having channel and colorspace together? Are there cases where they are interrelated?00034
00035 template <typename Channel,typename ColorSpace>
00036 struct jpeg_read_support_private {
00037 BOOST_STATIC_CONSTANT(bool,is_supported=false);
00038 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
00039 };
00040 template <>
00041 struct jpeg_read_support_private<bits8,gray_t> {
00042 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00043 BOOST_STATIC_CONSTANT(bool,is_supported=true);
00044 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
00045 };
00046 template <>
00047 struct jpeg_read_support_private<bits8,rgb_t> {
00048 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00049 BOOST_STATIC_CONSTANT(bool,is_supported=true);
00050 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
00051 };
00052 template <>
00053 struct jpeg_read_support_private<bits8,cmyk_t> {
00054 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00055 BOOST_STATIC_CONSTANT(bool,is_supported=true);
00056 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
00057 };
00058 template <typename Channel,typename ColorSpace>
00059 struct jpeg_write_support_private {
00060 BOOST_STATIC_CONSTANT(bool,is_supported=false);
00061 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
00062 };
00063 template <>
00064 struct jpeg_write_support_private<bits8,gray_t> {
00065 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00066 BOOST_STATIC_CONSTANT(bool,is_supported=true);
00067 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
00068 };
00069 template <>
00070 struct jpeg_write_support_private<bits8,rgb_t> {
00071 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00072 BOOST_STATIC_CONSTANT(bool,is_supported=true);
00073 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
00074 };
00075 template <>
00076 struct jpeg_write_support_private<bits8,cmyk_t> {
00077 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00078 BOOST_STATIC_CONSTANT(bool,is_supported=true);
00079 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
00080 };
00081
00082
00083 class jpeg_reader : public file_mgr {
00084 protected:
00085 jpeg_decompress_struct _cinfo;
00086 jpeg_error_mgr _jerr;
00087
00088 void init() {
00089 _cinfo.err=jpeg_std_error(&_jerr);
00090 jpeg_create_decompress(&_cinfo);
00091 jpeg_stdio_src(&_cinfo,_fp.get());
00092 jpeg_read_header(&_cinfo,TRUE);
00093 }
00094 public:
00095 jpeg_reader(FILE* file) : file_mgr(file) { init(); }
00096 jpeg_reader(constchar* filename) : file_mgr(filename, "rb") { init(); }
00097
00098 ~jpeg_reader() { jpeg_destroy_decompress(&_cinfo); }
00099
00100 template <typename View>
00101 void apply(const View& view) {
00102 jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...00103 io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported");
00104 io_error_if(_cinfo.out_color_space!=jpeg_read_support_private<typename channel_type<View>::type,
00105 typename color_space_type<View>::type>::color_type,
00106 "jpeg_reader::apply(): input view type does not match the image file");
00107 io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file");
00108 std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
00109 JSAMPLE* row_address=(JSAMPLE*)&row.front();
00110 for(int y=0;y<view.height();++y) {
00111 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00112 "jpeg_reader::apply(): fail to read JPEG file");
00113 std::copy(row.begin(),row.end(),view.row_begin(y));
00114 }
00115 jpeg_finish_decompress(&_cinfo);
00116 }
00117
00118 template <typename Image>
00119 void read_image(Image& im) {
00120 im.recreate(get_dimensions());
00121 apply(view(im));
00122 }
00123
00124 point2<std::ptrdiff_t> get_dimensions() const {
00125 return point2<std::ptrdiff_t>(_cinfo.image_width,_cinfo.image_height);
00126 }
00127 };
00128
00129 // This code will be simplified...00130 template <typename CC>
00131 class jpeg_reader_color_convert : public jpeg_reader {
00132 private:
00133 CC _cc;
00134 public:
00135 jpeg_reader_color_convert(FILE* file,CC cc_in) : jpeg_reader(file),_cc(cc_in) {}
00136 jpeg_reader_color_convert(FILE* file) : jpeg_reader(file) {}
00137 jpeg_reader_color_convert(constchar* filename,CC cc_in) : jpeg_reader(filename),_cc(cc_in) {}
00138 jpeg_reader_color_convert(constchar* filename) : jpeg_reader(filename) {}
00139 template <typename View>
00140 void apply(const View& view) {
00141 jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...00142 io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported");
00143 io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file");
00144 switch (_cinfo.out_color_space) {
00145 case JCS_GRAYSCALE: {
00146 std::vector<gray8_pixel_t> row(view.width());
00147 JSAMPLE* row_address=(JSAMPLE*)&row.front();
00148 for(int y=0;y<view.height();++y) {
00149 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00150 "jpeg_reader_color_covert::apply(): fail to read JPEG file");
00151 std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t, typename View::value_type,CC>(_cc));
00152 }
00153 break;
00154 }
00155 case JCS_RGB: {
00156 std::vector<rgb8_pixel_t> row(view.width());
00157 JSAMPLE* row_address=(JSAMPLE*)&row.front();
00158 for(int y=0;y<view.height();++y) {
00159 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00160 "jpeg_reader_color_covert::apply(): fail to read JPEG file");
00161 std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t, typename View::value_type,CC>(_cc));
00162 }
00163 break;
00164 }
00165 case JCS_CMYK: {
00166 std::vector<cmyk8_pixel_t> row(view.width());
00167 JSAMPLE* row_address=(JSAMPLE*)&row.front();
00168 for(int y=0;y<view.height();++y) {
00169 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00170 "jpeg_reader_color_covert::apply(): fail to read JPEG file");
00171 std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<cmyk8_ref_t, typename View::value_type,CC>(_cc));
00172 }
00173 break;
00174 }
00175 default:
00176 io_error("jpeg_reader_color_covert::apply(): unknown color type");
00177 }
00178 jpeg_finish_decompress(&_cinfo);
00179 }
00180 template <typename Image>
00181 void read_image(Image& im) {
00182 im.recreate(get_dimensions());
00183 apply(view(im));
00184 }
00185 };
00186
00187 class jpeg_writer : public file_mgr {
00188 jpeg_compress_struct _cinfo;
00189 jpeg_error_mgr _jerr;
00190
00191 void init() {
00192 _cinfo.err=jpeg_std_error(&_jerr);
00193 jpeg_create_compress(&_cinfo);
00194 jpeg_stdio_dest(&_cinfo,_fp.get());
00195 }
00196 public:
00197 jpeg_writer(FILE* file) : file_mgr(file) { init(); }
00198 jpeg_writer(constchar* filename) : file_mgr(filename, "wb") { init(); }
00199 ~jpeg_writer() { jpeg_destroy_compress(&_cinfo); }
00200
00201 template <typename View>
00202 void apply(const View& view,int quality=100) {
00203 _cinfo.image_width = (JDIMENSION)view.width();
00204 _cinfo.image_height = (JDIMENSION)view.height();
00205 _cinfo.input_components=num_channels<View>::value;
00206 _cinfo.in_color_space = jpeg_write_support_private<typename channel_type<View>::type,
00207 typename color_space_type<View>::type>::color_type;
00208 jpeg_set_defaults(&_cinfo);
00209 jpeg_set_quality(&_cinfo, quality, TRUE);
00210 jpeg_start_compress(&_cinfo, TRUE);
00211 std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
00212 JSAMPLE* row_address=(JSAMPLE*)&row.front();
00213 for (int y=0;y<view.height(); ++y) {
00214 std::copy(view.row_begin(y),view.row_end(y),row.begin());
00215 io_error_if(jpeg_write_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1) != 1,
00216 "jpeg_writer::apply(): fail to write file");
00217 }
00218 jpeg_finish_compress(&_cinfo);
00219 }
00220 };
00221
00222 } // namespace detail00223
00224 } } // namespace boost::gil00225
00226 #endif
Generated on Sat May 2 13:50:14 2009 for Generic Image Library by
1.5.6
Статья Generic Image Library: jpeg_io_private.hpp Source File раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.