1 //
2 // Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #ifndef BOOST_GIL_EXTENSION_IO_JPEG_TAGS_HPP
9 #define BOOST_GIL_EXTENSION_IO_JPEG_TAGS_HPP
10 
11 // taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
12 #ifndef BOOST_GIL_EXTENSION_IO_JPEG_C_LIB_COMPILED_AS_CPLUSPLUS
13     extern "C" {
14 #else
15     // DONT_USE_EXTERN_C introduced in v7 of the IJG library.
16     // By default the v7 IJG headers check for __cplusplus being defined and
17     // wrap the content in an 'extern "C"' block if it's present.
18     // When DONT_USE_EXTERN_C is defined, this wrapping is not performed.
19     #ifndef DONT_USE_EXTERN_C
20         #define DONT_USE_EXTERN_C 1
21     #endif
22 #endif
23 
24 #include <cstdio> // jpeglib doesn't know about FILE
25 
26 #include <jerror.h>
27 #include <jpeglib.h>
28 
29 #ifndef BOOST_GIL_EXTENSION_IO_JPEG_C_LIB_COMPILED_AS_CPLUSPLUS
30     }
31 #endif
32 
33 #include <boost/gil/io/base.hpp>
34 
35 namespace boost { namespace gil {
36 
37 /// Defines jpeg tag.
38 struct jpeg_tag : format_tag {};
39 
40 /// see http://en.wikipedia.org/wiki/JPEG for reference
41 
42 /// Defines type for image width property.
43 struct jpeg_image_width : property_base< JDIMENSION > {};
44 
45 /// Defines type for image height property.
46 struct jpeg_image_height : property_base< JDIMENSION > {};
47 
48 /// Defines type for number of components property.
49 struct jpeg_num_components : property_base< int > {};
50 
51 /// Defines type for color space property.
52 struct jpeg_color_space : property_base< J_COLOR_SPACE > {};
53 
54 /// Defines type for jpeg quality property.
55 struct jpeg_quality : property_base< int >
56 {
57     static const type default_value = 100;
58 };
59 
60 /// Defines type for data precision property.
61 struct jpeg_data_precision : property_base< int > {};
62 
63 /// JFIF code for pixel size units
64 struct jpeg_density_unit : property_base< UINT8 >
65 {
66     static const type default_value = 0;
67 };
68 
69 /// pixel density
70 struct jpeg_pixel_density : property_base< UINT16 >
71 {
72     static const type default_value = 0;
73 };
74 
75 /// Defines type for dct ( discrete cosine transformation ) method property.
76 struct jpeg_dct_method : property_base< J_DCT_METHOD >
77 {
78     static const type slow        = JDCT_ISLOW;
79     static const type fast        = JDCT_IFAST;
80     static const type floating_pt = JDCT_FLOAT;
81     static const type fastest     = JDCT_FASTEST;
82 
83     static const type default_value = slow;
84 };
85 
86 /// Read information for jpeg images.
87 ///
88 /// The structure is returned when using read_image_info.
89 template<>
90 struct image_read_info< jpeg_tag >
91 {
image_read_infoboost::gil::image_read_info92     image_read_info()
93     : _width ( 0 )
94     , _height( 0 )
95 
96     , _num_components( 0 )
97 
98     , _color_space( J_COLOR_SPACE( 0 ))
99 
100     , _data_precision( 0 )
101 
102     , _density_unit ( 0 )
103     , _x_density    ( 0 )
104     , _y_density    ( 0 )
105 
106     , _pixel_width_mm ( 0.0 )
107     , _pixel_height_mm( 0.0 )
108     {}
109 
110     /// The image width.
111     jpeg_image_width::type _width;
112 
113     /// The image height.
114     jpeg_image_height::type _height;
115 
116     /// The number of channels.
117     jpeg_num_components::type _num_components;
118 
119     /// The color space.
120     jpeg_color_space::type _color_space;
121 
122     /// The width of channel.
123     /// I believe this number is always 8 in the case libjpeg is built with 8.
124     /// see: http://www.asmail.be/msg0055405033.html
125     jpeg_data_precision::type _data_precision;
126 
127     /// Density conversion unit.
128     jpeg_density_unit::type  _density_unit;
129     jpeg_pixel_density::type _x_density;
130     jpeg_pixel_density::type _y_density;
131 
132     /// Real-world dimensions
133     double _pixel_width_mm;
134     double _pixel_height_mm;
135 };
136 
137 /// Read settings for jpeg images.
138 ///
139 /// The structure can be used for all read_xxx functions, except read_image_info.
140 template<>
141 struct image_read_settings< jpeg_tag > : public image_read_settings_base
142 {
143     /// Default constructor
144     image_read_settings<jpeg_tag>()
145     : image_read_settings_base()
146     , _dct_method( jpeg_dct_method::default_value )
147     {}
148 
149     /// Constructor
150     /// \param top_left   Top left coordinate for reading partial image.
151     /// \param dim        Dimensions for reading partial image.
152     /// \param dct_method Specifies dct method.
image_read_settingsboost::gil::image_read_settings153     image_read_settings( const point_t&        top_left
154                        , const point_t&        dim
155                        , jpeg_dct_method::type dct_method = jpeg_dct_method::default_value
156                        )
157     : image_read_settings_base( top_left
158                               , dim
159                               )
160     , _dct_method( dct_method )
161     {}
162 
163     /// The dct ( discrete cosine transformation ) method.
164     jpeg_dct_method::type _dct_method;
165 };
166 
167 /// Write information for jpeg images.
168 ///
169 /// The structure can be used for write_view() function.
170 template<>
171 struct image_write_info< jpeg_tag >
172 {
173     /// Constructor
174     /// \param quality      Defines the jpeg quality.
175     /// \param dct_method   Defines the DCT method.
176     /// \param density_unit Defines the density unit.
177     /// \param x_density    Defines the x density.
178     /// \param y_density    Defines the y density.
image_write_infoboost::gil::image_write_info179     image_write_info( const jpeg_quality::type    quality        = jpeg_quality::default_value
180                     , const jpeg_dct_method::type dct_method     = jpeg_dct_method::default_value
181                     , const jpeg_density_unit::type density_unit = jpeg_density_unit::default_value
182                     , const jpeg_pixel_density::type x_density   = jpeg_pixel_density::default_value
183                     , const jpeg_pixel_density::type y_density   = jpeg_pixel_density::default_value
184                     )
185     : _quality   ( quality    )
186     , _dct_method( dct_method )
187 
188     , _density_unit( density_unit )
189     , _x_density   ( x_density    )
190     , _y_density   ( y_density    )
191     {}
192 
193     /// The jpeg quality.
194     jpeg_quality::type _quality;
195 
196     /// The dct ( discrete cosine transformation ) method.
197     jpeg_dct_method::type _dct_method;
198 
199     /// Density conversion unit.
200     jpeg_density_unit::type _density_unit;
201 
202     /// Pixel density dimensions.
203     jpeg_pixel_density::type _x_density;
204     jpeg_pixel_density::type _y_density;
205 
206     /// Sets the pixel dimensions.
set_pixel_dimensionsboost::gil::image_write_info207     void set_pixel_dimensions( int    image_width   // in pixels
208                              , int    image_height  // in pixels
209                              , double pixel_width   // in mm
210                              , double pixel_height  // in mm
211                              )
212     {
213         _density_unit = 2; // dots per cm
214 
215         _x_density = round( image_width  / ( pixel_width  / 10 ));
216         _y_density = round( image_height / ( pixel_height / 10 ));
217     }
218 
219 private:
220 
roundboost::gil::image_write_info221     UINT16 round( double d )
222     {
223         return static_cast< UINT16 >( d + 0.5 );
224     }
225 
226 };
227 
228 } // namespace gil
229 } // namespace boost
230 
231 #endif
232