1 /************************************************************************/
2 /*                                                                      */
3 /*               Copyright 2001-2002 by Gunnar Kedenburg                */
4 /*                                                                      */
5 /*    This file is part of the VIGRA computer vision library.           */
6 /*    The VIGRA Website is                                              */
7 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
8 /*    Please direct questions, bug reports, and contributions to        */
9 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
10 /*        vigra@informatik.uni-hamburg.de                               */
11 /*                                                                      */
12 /*    Permission is hereby granted, free of charge, to any person       */
13 /*    obtaining a copy of this software and associated documentation    */
14 /*    files (the "Software"), to deal in the Software without           */
15 /*    restriction, including without limitation the rights to use,      */
16 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
17 /*    sell copies of the Software, and to permit persons to whom the    */
18 /*    Software is furnished to do so, subject to the following          */
19 /*    conditions:                                                       */
20 /*                                                                      */
21 /*    The above copyright notice and this permission notice shall be    */
22 /*    included in all copies or substantial portions of the             */
23 /*    Software.                                                         */
24 /*                                                                      */
25 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
26 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
27 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
28 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
29 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
30 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
31 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
32 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
33 /*                                                                      */
34 /************************************************************************/
35 
36 /* Modifications by Pablo d'Angelo
37  * updated to vigra 1.4 by Douglas Wilkins
38  * as of 18 February 2006:
39  *  - Added UINT16 and UINT32 pixel types.
40  *  - Added support for obtaining extra bands beyond RGB.
41  *  - Added support for a position field that indicates the start of this
42  *    image relative to some global origin.
43  *  - Added support for x and y resolution fields.
44  *  - Added support for ICC Profiles
45  */
46 
47 #ifndef VIGRA_CODEC_HXX
48 #define VIGRA_CODEC_HXX
49 
50 #include <memory>
51 #include <string>
52 #include <vector>
53 
54 #include "array_vector.hxx"
55 #include "config.hxx"
56 #include "diff2d.hxx"
57 #include "sized_int.hxx"
58 
59 // possible pixel types:
60 // "undefined", "UINT8", "UINT16", "INT16", "UINT32", "INT32", "FLOAT", "DOUBLE"
61 
62 // possible compression types:
63 // "undefined", "RLE", "LZW", "LOSSLESS", "JPEG", "DEFLATE"
64 
65 // possible file types:
66 // "undefined", "TIFF", "VIFF", "JPEG", "PNG", "PNM", "BMP", "SUN", "XPM", "EXR"
67 
68 // possible name extensions:
69 // "undefined", "tif", "tiff", "jpg", "jpeg", "png", "pnm", "bmp", "sun",
70 // "xpm", "exr" (also capital forms)
71 
72 namespace vigra
73 {
74     template <class T>
75     struct TypeAsString
76     {
resultvigra::TypeAsString77         static std::string result() { return "undefined"; }
78     };
79 
80     template <>
81     struct TypeAsString<Int8>
82     {
resultvigra::TypeAsString83         static std::string result() { return "INT8"; }
84     };
85 
86     template <>
87     struct TypeAsString<UInt8>
88     {
resultvigra::TypeAsString89         static std::string result() { return "UINT8"; }
90     };
91 
92     template <>
93     struct TypeAsString<Int16>
94     {
resultvigra::TypeAsString95         static std::string result() { return "INT16"; }
96     };
97 
98     template <>
99     struct TypeAsString<UInt16>
100     {
resultvigra::TypeAsString101         static std::string result() { return "UINT16"; }
102     };
103 
104     template <>
105     struct TypeAsString<Int32>
106     {
resultvigra::TypeAsString107         static std::string result() { return "INT32"; }
108     };
109 
110     template <>
111     struct TypeAsString<UInt32>
112     {
resultvigra::TypeAsString113         static std::string result() { return "UINT32"; }
114     };
115 
116     template <>
117     struct TypeAsString<float>
118     {
resultvigra::TypeAsString119         static std::string result() { return "FLOAT"; }
120     };
121 
122     template <>
123     struct TypeAsString<double>
124     {
resultvigra::TypeAsString125         static std::string result() { return "DOUBLE"; }
126     };
127 
128 
129     // codec description
130     struct CodecDesc
131     {
132         std::string fileType;
133         std::vector<std::string> pixelTypes;
134         std::vector<std::string> compressionTypes;
135         std::vector<std::vector<char> > magicStrings;
136         std::vector<std::string> fileExtensions;
137         std::vector<int> bandNumbers;
138     };
139 
140     // Decoder and Encoder are virtual types that define a common
141     // interface for all image file formats impex supports.
142 
143     struct Decoder
144     {
~Decodervigra::Decoder145         virtual ~Decoder() {};
146         virtual void init( const std::string & ) = 0;
147 
148         // initialize with an image index. For codecs that do not support this feature, the standard init is called.
initvigra::Decoder149         virtual void init( const std::string & fileName, unsigned int)
150         {
151           init(fileName);
152         }
153 
154         virtual void close() = 0;
155         virtual void abort() = 0;
156 
157         virtual std::string getFileType() const = 0;
158         virtual std::string getPixelType() const = 0;
159 
getNumImagesvigra::Decoder160         virtual unsigned int getNumImages() const
161         {
162           return 1;
163         }
164 
setImageIndexvigra::Decoder165         virtual void setImageIndex(unsigned int)
166         {
167         }
168 
getImageIndexvigra::Decoder169         virtual unsigned int getImageIndex() const
170         {
171           return 0;
172         }
173 
174         virtual unsigned int getWidth() const = 0;
175         virtual unsigned int getHeight() const = 0;
176         virtual unsigned int getNumBands() const = 0;
getNumExtraBandsvigra::Decoder177         virtual unsigned int getNumExtraBands() const
178         {
179             return 0;
180         }
181 
getPositionvigra::Decoder182         virtual vigra::Diff2D getPosition() const
183         {
184             return vigra::Diff2D();
185         }
186 
getXResolutionvigra::Decoder187         virtual float getXResolution() const
188         {
189             return 0.0f;
190         }
getYResolutionvigra::Decoder191         virtual float getYResolution() const
192         {
193             return 0.0f;
194         }
195 
getCanvasSizevigra::Decoder196         virtual vigra::Size2D getCanvasSize() const
197         {
198             return vigra::Size2D(this->getWidth(), this->getHeight());
199         }
200 
201         virtual unsigned int getOffset() const = 0;
202 
203         virtual const void * currentScanlineOfBand( unsigned int ) const = 0;
204         virtual void nextScanline() = 0;
205 
206         typedef ArrayVector<unsigned char> ICCProfile;
207 
getICCProfilevigra::Decoder208         const ICCProfile & getICCProfile() const
209         {
210             return iccProfile_;
211         }
212 
213         ICCProfile iccProfile_;
214     };
215 
216     struct Encoder
217     {
~Encodervigra::Encoder218         virtual ~Encoder() {};
219         virtual void init( const std::string & ) = 0;
220 
221         // initialize with file access mode. For codecs that do not support this feature, the standard init is called.
initvigra::Encoder222         virtual void init( const std::string & fileName, const std::string & )
223         {
224           init(fileName);
225         }
226 
227         virtual void close() = 0;
228         virtual void abort() = 0;
229 
230         virtual std::string getFileType() const = 0;
231         virtual unsigned int getOffset() const = 0;
232 
233         virtual void setWidth( unsigned int ) = 0;
234         virtual void setHeight( unsigned int ) = 0;
235         virtual void setNumBands( unsigned int ) = 0;
236         virtual void setCompressionType( const std::string &, int = -1 ) = 0;
237         virtual void setPixelType( const std::string & ) = 0;
238         virtual void finalizeSettings() = 0;
239 
setPositionvigra::Encoder240         virtual void setPosition( const vigra::Diff2D & /*pos*/ )
241         {
242         }
setCanvasSizevigra::Encoder243         virtual void setCanvasSize( const vigra::Size2D & /*size*/)
244         {
245         }
setXResolutionvigra::Encoder246         virtual void setXResolution( float /*xres*/ )
247         {
248         }
setYResolutionvigra::Encoder249         virtual void setYResolution( float /*yres*/ )
250         {
251         }
252 
253         typedef ArrayVector<unsigned char> ICCProfile;
254 
setICCProfilevigra::Encoder255         virtual void setICCProfile(const ICCProfile & /* data */)
256         {
257         }
258 
259         virtual void * currentScanlineOfBand( unsigned int ) = 0;
260         virtual void nextScanline() = 0;
261 
262         struct TIFFCompressionException {};
263     };
264 
265     // codec factory for registration at the codec manager
266 
267     struct CodecFactory
268     {
269         virtual CodecDesc getCodecDesc() const = 0;
270         virtual VIGRA_UNIQUE_PTR<Decoder> getDecoder() const = 0;
271         virtual VIGRA_UNIQUE_PTR<Encoder> getEncoder() const = 0;
~CodecFactoryvigra::CodecFactory272         virtual ~CodecFactory() {};
273     };
274 
275     // factory functions to encapsulate the codec managers
276     //
277     // codecs are selected according to the following order:
278     // - (if provided) the FileType
279     // - (in case of decoders) the file's magic string
280     // - the filename extension
281 
282     VIGRA_EXPORT VIGRA_UNIQUE_PTR<Decoder>
283     getDecoder( const std::string &, const std::string & = "undefined", unsigned int = 0 );
284 
285     VIGRA_EXPORT VIGRA_UNIQUE_PTR<Encoder>
286     getEncoder( const std::string &, const std::string & = "undefined", const std::string & = "w" );
287 
288     VIGRA_EXPORT std::string
289     getEncoderType( const std::string &, const std::string & = "undefined" );
290 
291     // functions to query the capabilities of certain codecs
292 
293     VIGRA_EXPORT std::vector<std::string> queryCodecPixelTypes( const std::string & );
294 
295     VIGRA_EXPORT bool negotiatePixelType( std::string const & codecname,
296                  std::string const & srcPixeltype, std::string & destPixeltype);
297 
298     VIGRA_EXPORT bool isPixelTypeSupported( const std::string &, const std::string & );
299 
300     VIGRA_EXPORT bool isBandNumberSupported( const std::string &, int bands );
301 }
302 
303 #endif // VIGRA_CODEC_HXX
304