Adobe Systems, Inc.

jpeg_io_private.hpp

Go to the documentation of this file.
00001 /*
00002   Copyright 2005-2006 Adobe Systems Incorporated
00003   Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004   or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef GIL_JPEG_IO_PRIVATE_H
00010 #define GIL_JPEG_IO_PRIVATE_H
00011 
00017 
00018 #include <stdio.h>
00019 #include <boost/static_assert.hpp>
00020 #include <vector>
00021 #include <jpeglib.h>
00022 #include "../../core/gil_all.hpp"
00023 #include "io_error.hpp"
00024 
00025 ADOBE_GIL_NAMESPACE_BEGIN
00026 
00027 namespace detail {
00028 
00029 // lbourdev: What is the advantage of having channel and colorspace together? Are there cases where they are interrelated?
00030 
00031 template <typename CHANNEL,typename COLORSPACE>
00032 struct jpeg_read_support_private {
00033     BOOST_STATIC_CONSTANT(bool,is_supported=false);
00034     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
00035 };
00036 template <>
00037 struct jpeg_read_support_private<bits8,gray_t> {
00038     BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00039     BOOST_STATIC_CONSTANT(bool,is_supported=true);
00040     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
00041 };
00042 template <>
00043 struct jpeg_read_support_private<bits8,rgb_t> {
00044     BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00045     BOOST_STATIC_CONSTANT(bool,is_supported=true);
00046     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
00047 };
00048 template <>
00049 struct jpeg_read_support_private<bits8,cmyk_t> {
00050     BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00051     BOOST_STATIC_CONSTANT(bool,is_supported=true);
00052     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
00053 };
00054 template <typename CHANNEL,typename COLORSPACE>
00055 struct jpeg_write_support_private {
00056     BOOST_STATIC_CONSTANT(bool,is_supported=false);
00057     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
00058 };
00059 template <>
00060 struct jpeg_write_support_private<bits8,gray_t> {
00061     BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00062     BOOST_STATIC_CONSTANT(bool,is_supported=true);
00063     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
00064 };
00065 template <>
00066 struct jpeg_write_support_private<bits8,rgb_t> {
00067     BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00068     BOOST_STATIC_CONSTANT(bool,is_supported=true);
00069     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
00070 };
00071 template <>
00072 struct jpeg_write_support_private<bits8,cmyk_t> {
00073     BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
00074     BOOST_STATIC_CONSTANT(bool,is_supported=true);
00075     BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
00076 };
00077 
00078 
00079 class jpeg_reader : public file_mgr {
00080 protected:
00081     jpeg_decompress_struct  _cinfo;
00082     jpeg_error_mgr          _jerr;
00083 
00084     void init() {
00085         _cinfo.err=jpeg_std_error(&_jerr);
00086         jpeg_create_decompress(&_cinfo);
00087         jpeg_stdio_src(&_cinfo,_fp.get());
00088         jpeg_read_header(&_cinfo,TRUE);
00089     }
00090 public:
00091     jpeg_reader(FILE* file)           : file_mgr(file)           { init(); }
00092     jpeg_reader(const char* filename) : file_mgr(filename, "rb") { init(); }
00093 
00094     ~jpeg_reader() { jpeg_destroy_decompress(&_cinfo); }
00095 
00096     template <typename VIEW>
00097     void apply(const VIEW& view) {
00098         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...
00099         io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported");
00100         io_error_if(_cinfo.out_color_space!=jpeg_read_support_private<typename VIEW::channel_t,
00101                                                                       typename VIEW::color_space_t::base>::color_type,
00102                     "jpeg_reader::apply(): input view type does not match the image file");
00103         io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file");
00104         std::vector<pixel<bits8,typename VIEW::color_space_t::base> > row(view.width());
00105         JSAMPLE* row_address=(JSAMPLE*)&row.front();
00106         for(int y=0;y<view.height();++y) {
00107             io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00108                         "jpeg_reader::apply(): fail to read JPEG file");
00109             std::copy(row.begin(),row.end(),view.row_begin(y));
00110         }
00111         jpeg_finish_decompress(&_cinfo);
00112     }
00113     
00114     template <typename IMAGE>
00115     void read_image(IMAGE& im) {
00116         resize_clobber_image(im,get_dimensions());
00117         apply(view(im));
00118     }
00119 
00120     point2<int> get_dimensions() const {
00121         return point2<int>(_cinfo.image_width,_cinfo.image_height);
00122     }
00123 };
00124 
00125 // This code will be simplified...
00126 class jpeg_reader_color_convert : public jpeg_reader {
00127 public:
00128     jpeg_reader_color_convert(FILE* file)           : jpeg_reader(file) {}
00129     jpeg_reader_color_convert(const char* filename) : jpeg_reader(filename) {}
00130     template <typename VIEW>
00131     void apply(const VIEW& view) {
00132         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...
00133         io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported");
00134         io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file");
00135         switch (_cinfo.out_color_space) {
00136         case JCS_GRAYSCALE: {
00137             std::vector<pixel<bits8,gray_t> > row(view.width());
00138             JSAMPLE* row_address=(JSAMPLE*)&row.front();
00139             for(int y=0;y<view.height();++y) {
00140                 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00141                             "jpeg_reader_color_covert::apply(): fail to read JPEG file");
00142                 std::transform(row.begin(),row.end(),view.row_begin(y),
00143                                color_converter<typename VIEW::pixel_t>());
00144             }
00145             break;
00146         }
00147         case JCS_RGB: {
00148             std::vector<pixel<bits8,rgb_t> > row(view.width());
00149             JSAMPLE* row_address=(JSAMPLE*)&row.front();
00150             for(int y=0;y<view.height();++y) {
00151                 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00152                             "jpeg_reader_color_covert::apply(): fail to read JPEG file");
00153                 std::transform(row.begin(),row.end(),view.row_begin(y),
00154                                color_converter<typename VIEW::pixel_t>());
00155             }
00156             break;
00157         }
00158         case JCS_CMYK: {
00159             std::vector<pixel<bits8,cmyk_t> > row(view.width());
00160             JSAMPLE* row_address=(JSAMPLE*)&row.front();
00161             for(int y=0;y<view.height();++y) {
00162                 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
00163                             "jpeg_reader_color_covert::apply(): fail to read JPEG file");
00164                 std::transform(row.begin(),row.end(),view.row_begin(y),
00165                                color_converter<typename VIEW::pixel_t>());
00166             }
00167             break;
00168         }
00169         default:
00170             io_error("jpeg_reader_color_covert::apply(): unknown color type");
00171         }
00172         jpeg_finish_decompress(&_cinfo);
00173     }    
00174     template <typename IMAGE>
00175     void read_image(IMAGE& im) {
00176         resize_clobber_image(im,get_dimensions());
00177         apply(view(im));
00178     }
00179 };
00180 
00181 class jpeg_writer : public file_mgr {
00182     jpeg_compress_struct _cinfo;
00183     jpeg_error_mgr _jerr;
00184 
00185     void init() {
00186         _cinfo.err=jpeg_std_error(&_jerr);
00187         jpeg_create_compress(&_cinfo);
00188         jpeg_stdio_dest(&_cinfo,_fp.get());
00189     }
00190 public:
00191     jpeg_writer(FILE* file)           : file_mgr(file)           { init(); }
00192     jpeg_writer(const char* filename) : file_mgr(filename, "wb") { init(); }
00193     ~jpeg_writer() { jpeg_destroy_compress(&_cinfo); }
00194     
00195     template <typename VIEW>
00196     void apply(const VIEW& view,int quality=100) {
00197         _cinfo.image_width  = (JDIMENSION)view.width();
00198         _cinfo.image_height = (JDIMENSION)view.height();
00199         _cinfo.input_components=VIEW::color_space_t::num_channels;
00200         _cinfo.in_color_space = jpeg_write_support_private<typename VIEW::channel_t,
00201                                                            typename VIEW::color_space_t::base>::color_type;
00202         jpeg_set_defaults(&_cinfo);
00203         jpeg_set_quality(&_cinfo, quality, TRUE);
00204         jpeg_start_compress(&_cinfo, TRUE);
00205         std::vector<pixel<bits8,typename VIEW::color_space_t::base> > row(view.width());
00206         JSAMPLE* row_address=(JSAMPLE*)&row.front();
00207         for (int y=0;y<view.height(); ++y) {
00208             std::copy(view.row_begin(y),view.row_end(y),row.begin());
00209             io_error_if(jpeg_write_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1) != 1,
00210                         "jpeg_writer::apply(): fail to write file");
00211         }
00212         jpeg_finish_compress(&_cinfo);
00213     }
00214 };
00215 
00216 } // namespace detail
00217 
00218 ADOBE_GIL_NAMESPACE_END
00219 
00220 #endif

Copyright © 2006 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google