]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/gil/include/boost/gil/extension/io/jpeg_io_private.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / gil / include / boost / gil / extension / io / jpeg_io_private.hpp
CommitLineData
7c673cae
FG
1/*
2 Copyright 2005-2007 Adobe Systems Incorporated
3
4 Use, modification and distribution are subject to the Boost Software License,
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7
8 See http://opensource.adobe.com/gil for most recent version including documentation.
9*/
10
11/*************************************************************************************************/
12
13#ifndef GIL_JPEG_IO_PRIVATE_H
14#define GIL_JPEG_IO_PRIVATE_H
15
16/// \file
17/// \brief Internal support for reading and writing JPEG files
18/// \author Hailin Jin and Lubomir Bourdev \n
19/// Adobe Systems Incorporated
20/// \date 2005-2007 \n Last updated September 24, 2006
21
22#include <stdio.h>
23#include <boost/static_assert.hpp>
24#include <vector>
25#include "../../gil_all.hpp"
26#include "io_error.hpp"
27#include <jpeglib.h>
28
29namespace boost { namespace gil {
30
31namespace detail {
32
33// lbourdev: What is the advantage of having channel and colorspace together? Are there cases where they are interrelated?
34
35template <typename Channel,typename ColorSpace>
36struct jpeg_read_support_private {
37 BOOST_STATIC_CONSTANT(bool,is_supported=false);
38 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
39};
40template <>
41struct jpeg_read_support_private<bits8,gray_t> {
42 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
43 BOOST_STATIC_CONSTANT(bool,is_supported=true);
44 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
45};
46template <>
47struct jpeg_read_support_private<bits8,rgb_t> {
48 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
49 BOOST_STATIC_CONSTANT(bool,is_supported=true);
50 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
51};
52template <>
53struct jpeg_read_support_private<bits8,cmyk_t> {
54 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
55 BOOST_STATIC_CONSTANT(bool,is_supported=true);
56 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
57};
58template <typename Channel,typename ColorSpace>
59struct jpeg_write_support_private {
60 BOOST_STATIC_CONSTANT(bool,is_supported=false);
61 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
62};
63template <>
64struct jpeg_write_support_private<bits8,gray_t> {
65 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
66 BOOST_STATIC_CONSTANT(bool,is_supported=true);
67 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
68};
69template <>
70struct jpeg_write_support_private<bits8,rgb_t> {
71 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
72 BOOST_STATIC_CONSTANT(bool,is_supported=true);
73 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
74};
75template <>
76struct jpeg_write_support_private<bits8,cmyk_t> {
77 BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
78 BOOST_STATIC_CONSTANT(bool,is_supported=true);
79 BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
80};
81
82
83class jpeg_reader : public file_mgr {
84protected:
85 jpeg_decompress_struct _cinfo;
86 jpeg_error_mgr _jerr;
87
88 void init() {
89 _cinfo.err=jpeg_std_error(&_jerr);
90 jpeg_create_decompress(&_cinfo);
91 jpeg_stdio_src(&_cinfo,_fp.get());
92 jpeg_read_header(&_cinfo,TRUE);
93 }
94public:
95 jpeg_reader(FILE* file) : file_mgr(file) { init(); }
96 jpeg_reader(const char* filename) : file_mgr(filename, "rb") { init(); }
97
98 ~jpeg_reader() { jpeg_destroy_decompress(&_cinfo); }
99
100 template <typename View>
101 void apply(const View& view) {
102 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...
103 io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported");
104 io_error_if(_cinfo.out_color_space!=jpeg_read_support_private<typename channel_type<View>::type,
105 typename color_space_type<View>::type>::color_type,
106 "jpeg_reader::apply(): input view type does not match the image file");
107 io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file");
108 std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
109 JSAMPLE* row_address=(JSAMPLE*)&row.front();
110 for(int y=0;y<view.height();++y) {
111 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
112 "jpeg_reader::apply(): fail to read JPEG file");
113 std::copy(row.begin(),row.end(),view.row_begin(y));
114 }
115 jpeg_finish_decompress(&_cinfo);
116 }
117
118 template <typename Image>
119 void read_image(Image& im) {
120 im.recreate(get_dimensions());
121 apply(view(im));
122 }
123
124 point2<std::ptrdiff_t> get_dimensions() const {
125 return point2<std::ptrdiff_t>(_cinfo.image_width,_cinfo.image_height);
126 }
127};
128
129// This code will be simplified...
130template <typename CC>
131class jpeg_reader_color_convert : public jpeg_reader {
132private:
133 CC _cc;
134public:
135 jpeg_reader_color_convert(FILE* file,CC cc_in) : jpeg_reader(file),_cc(cc_in) {}
136 jpeg_reader_color_convert(FILE* file) : jpeg_reader(file) {}
137 jpeg_reader_color_convert(const char* filename,CC cc_in) : jpeg_reader(filename),_cc(cc_in) {}
138 jpeg_reader_color_convert(const char* filename) : jpeg_reader(filename) {}
139 template <typename View>
140 void apply(const View& view) {
141 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...
142 io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported");
143 io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file");
144 switch (_cinfo.out_color_space) {
145 case JCS_GRAYSCALE: {
146 std::vector<gray8_pixel_t> row(view.width());
147 JSAMPLE* row_address=(JSAMPLE*)&row.front();
148 for(int y=0;y<view.height();++y) {
149 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
150 "jpeg_reader_color_covert::apply(): fail to read JPEG file");
151 std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t, typename View::value_type,CC>(_cc));
152 }
153 break;
154 }
155 case JCS_RGB: {
156 std::vector<rgb8_pixel_t> row(view.width());
157 JSAMPLE* row_address=(JSAMPLE*)&row.front();
158 for(int y=0;y<view.height();++y) {
159 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
160 "jpeg_reader_color_covert::apply(): fail to read JPEG file");
161 std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t, typename View::value_type,CC>(_cc));
162 }
163 break;
164 }
165 case JCS_CMYK: {
166 std::vector<cmyk8_pixel_t> row(view.width());
167 JSAMPLE* row_address=(JSAMPLE*)&row.front();
168 for(int y=0;y<view.height();++y) {
169 io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
170 "jpeg_reader_color_covert::apply(): fail to read JPEG file");
171 std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<cmyk8_ref_t, typename View::value_type,CC>(_cc));
172 }
173 break;
174 }
175 default:
176 io_error("jpeg_reader_color_covert::apply(): unknown color type");
177 }
178 jpeg_finish_decompress(&_cinfo);
179 }
180 template <typename Image>
181 void read_image(Image& im) {
182 im.recreate(get_dimensions());
183 apply(view(im));
184 }
185};
186
187class jpeg_writer : public file_mgr {
188 jpeg_compress_struct _cinfo;
189 jpeg_error_mgr _jerr;
190
191 void init() {
192 _cinfo.err=jpeg_std_error(&_jerr);
193 jpeg_create_compress(&_cinfo);
194 jpeg_stdio_dest(&_cinfo,_fp.get());
195 }
196public:
197 jpeg_writer(FILE* file) : file_mgr(file) { init(); }
198 jpeg_writer(const char* filename) : file_mgr(filename, "wb") { init(); }
199 ~jpeg_writer() { jpeg_destroy_compress(&_cinfo); }
200
201 template <typename View>
202 void apply(const View& view,int quality=100) {
203 _cinfo.image_width = (JDIMENSION)view.width();
204 _cinfo.image_height = (JDIMENSION)view.height();
205 _cinfo.input_components=num_channels<View>::value;
206 _cinfo.in_color_space = jpeg_write_support_private<typename channel_type<View>::type,
207 typename color_space_type<View>::type>::color_type;
208 jpeg_set_defaults(&_cinfo);
209 jpeg_set_quality(&_cinfo, quality, TRUE);
210 jpeg_start_compress(&_cinfo, TRUE);
211 std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
212 JSAMPLE* row_address=(JSAMPLE*)&row.front();
213 for (int y=0;y<view.height(); ++y) {
214 std::copy(view.row_begin(y),view.row_end(y),row.begin());
215 io_error_if(jpeg_write_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1) != 1,
216 "jpeg_writer::apply(): fail to write file");
217 }
218 jpeg_finish_compress(&_cinfo);
219 }
220};
221
222} // namespace detail
223
224} } // namespace boost::gil
225
226#endif