File: Image.hh

package info (click to toggle)
exactimage 1.2.1-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,048 kB
  • sloc: cpp: 35,940; ansic: 1,952; xml: 1,447; makefile: 338; perl: 138; sh: 110; python: 45; php: 37; ruby: 12
file content (308 lines) | stat: -rw-r--r-- 7,570 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*
 * The Plain Old Data encapsulation of pixel, raster data.
 * Copyright (C) 2005 - 2023 René Rebe
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2. A copy of the GNU General
 * Public License can be found in the file LICENSE.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT-
 * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * Alternatively, commercial licensing options are available from the
 * copyright holder ExactCODE GmbH Germany.
 */

/* Only minimal abstraction is done here, to allow all sorts of
 * hand optimized low-level operations.
 *
 * While historically we only supported packed, byte-aligned scanlines,
 * since 2015 we also support abritrary strides. However, most algorithms
 * resizing the data usually compact the image to byte-aligned scanlines
 * without padding. Special care is needed not to iterate past a scanline.
 *
 * On load a codec might be attached. The codec might be querried
 * to decode the image data later on (decode on access) to allow
 * avoiding image decoding if the data is never accessed at all.
 *
 * Equivalently writing can be optimized by keeping the codec
 * around and saving the original data without recompression
 * (JPEG).
 *
 * Some methods in the codec allow working on the compressed data such
 * as orthogonal rotation, down-scaling, and cropping (e.g. of JPEG
 * DCT coefficients - like jpegtran, epeg).
 *
 * Call sequence on Read/Wrie:
 * to immediatly attach the data
 *   Image::New(w,h)
 *   Image::getRawData() // to write the data
 *   Image::setCodec()
 *
 * or to get on-demand decoding:
 *   set meta data (e.g. ::w, ::h, ::xdpi, ::ydpi, ...)
 *   Image::setRawData(0)
 *   Image::setCodec()
 *
 * Note: setCodec must be last as it marks the data as unmodifed.
 *
 * On access the data might be loaded on-demand:
 *   Image::getRawData()
 *     if !data then if codec then codec->decode() end end
 *
 * After modifing the POD image setRawData*() must be called to
 * notify about the update:
 *   Image::setRawData*()
 *     if !modified then codec->free() modified=true end 
 *
 * Again: If you modify more than meta data you must call:
 *   Image::setRawData()
 * even with the current data pointer remains equal to ensure
 * proper invalidation of the cached compressed codec data!
 *
 * Call sequence of the Codec's::encode*() if data is just rewritten:
 *     if image->isModified() then
 *       encode_new_data()
 *     else
 *       just copy existing compressed data (e.g. DCT)
 *     end
 *
 * The operator= create a complete clone of the image, the image
 * buffers are not shared (anymore, formerly ownership was passed and
 * we had a separate Clone() method). The attached codec is not
 * copied.
 */

#ifndef IMAGE_HH
#define IMAGE_HH

#include <stdint.h>
#include <string>
#include <math.h> // for floor

#include <iostream>

// just forward
class ImageCodec;

/// temp. state to migrate away from public member's
#define DEPRECATED
#ifndef DEPRECATED
#ifdef __GNUC__
#define DEPRECATED __attribute__ ((deprecated))
#endif
#endif

#define WARN_UNHANDLED std::cerr << "unhandled spp/bps in " << __FILE__ << ":" << __LINE__ << std::endl


class Image
{
protected:
  bool modified, meta_modified;
  int xres, yres;
  
  std::string decoderID;
  ImageCodec* codec;
  
  uint8_t* data;

public:
  
  uint8_t* getRawData () const;
  uint8_t* getRawDataEnd () const;

  void setRawData (); // just mark modified
  void setRawData (uint8_t* _data);
  void setRawDataWithoutDelete (uint8_t* _data);
  
  bool resize (int _w, int _h, unsigned stride = 0);
  void realloc ();
  void restride (unsigned newstride);
  
  void setDecoderID (const std::string& id);
  const std::string& getDecoderID ();
  ImageCodec* getCodec();
  void setCodec (ImageCodec* _codec);
  
  bool isModified () { return modified; }
  bool isMetaModified () { return meta_modified; }
  
  typedef enum {
    GRAY1 = 1,
    GRAY2,
    GRAY4,
    GRAY8,
    //    GRAY8A,
    GRAY16,
    //    GRAY16A,
    RGB8,
    RGBA8,
    RGB16,
    RGBA16,
    CMYK8,
    //    CMYK16,
    YUV8,
    // YUVK8 - really appears in the wild? JPEG appears to support this (Y/Cb/Cr/K)
  } type_t;

  typedef union {
    uint8_t gray;
    uint16_t gray16;
    struct {
      uint8_t r;
      uint8_t g;
      uint8_t b;
    } rgb;
    struct {
      uint8_t r;
      uint8_t g;
      uint8_t b;
      uint8_t a;
    } rgba;
    struct {
      uint16_t r;
      uint16_t g;
      uint16_t b;
    } rgb16;
    struct {
      uint16_t r;
      uint16_t g;
      uint16_t b;
      uint16_t a;
    } rgba16;
    struct {
      uint8_t c;
      uint8_t m;
      uint8_t y;
      uint8_t k;
    } cmyk;
    struct {
      uint8_t y;
      uint8_t u;
      uint8_t v;
    } yuv;
  } value_t;
    
  typedef union {
    int32_t gray;
    struct {
      int32_t r;
      int32_t g;
      int32_t b;
    } rgb;
    struct {
      int32_t r;
      int32_t g;
      int32_t b;
      int32_t a;
    } rgba;
    struct {
      int32_t c;
      int32_t m;
      int32_t y;
      int32_t k;
    } cmyk;
    struct {
      int32_t y;
      int32_t u;
      int32_t v;
    } yuv;
  } ivalue_t;

  int width () const { return w; }
  int height () const { return h; }
  
  unsigned stridefill () const;
  unsigned stride () const {
    return rowstride ? rowstride : stridefill();
  }
  
  uint8_t bitsPerSample () const { return bps; }
  uint8_t bitsPerPixel () const { return bps * spp; }
  uint8_t samplesPerPixel () const { return spp; }

  int resolutionX () const { return xres; }
  int resolutionY () const { return yres; }

  void setWidth (int _w) { w = _w; }
  void setHeight (int _h) { h = _h; }

  void setBitsPerSample (uint8_t _bps) { bps = _bps; }
  void setSamplesPerPixel (uint8_t _spp) { spp = _spp; }

  void setResolution (int _xres, int _yres) {
    if (xres != _xres || yres != _yres)
      meta_modified = true;
    xres = _xres;
    yres = _yres;
  }
  void setResolutionX (int _xres) { setResolution(_xres, yres); }
  void setResolutionY (int _yres) { setResolution(xres, _yres); }

  int w DEPRECATED, h DEPRECATED; // TODO: unsigned?
  uint8_t bps DEPRECATED, spp DEPRECATED;
  unsigned rowstride DEPRECATED;
  
public:
  
  Image ();
  Image (Image& other);
  ~Image ();
  
  
  Image& operator= (const Image& other);
  void copyTransferOwnership (Image& other);
  
  type_t Type () const {
    switch (spp*bps) {
    case 1:  return GRAY1;
    case 2:  return GRAY2;
    case 4:  return GRAY4;
    case 8:  return GRAY8;
    case 16: return GRAY16;
    case 24: return RGB8;
    case 32: return RGBA8;
    case 48: return RGB16;
    case 64: return RGBA16;
    default:
      WARN_UNHANDLED;
      return (Image::type_t)0;
    }
  }

#define CONST const
#include "ImageIterator.hh"
#include "ImageIterator.hh"

  const_iterator begin () const {
    return const_iterator (this, false);
  }

  const_iterator end () const {
    return const_iterator (this, true);
  }

  iterator begin () {
    return iterator (this, false);
  }
  
  iterator end () {
    return iterator (this, true);
  }

  void copyMeta (const Image& other);
  
protected:
};

typedef struct { uint8_t r, g, b; } rgb;
typedef struct { uint8_t r, g, b, a;} rgba;
typedef struct { uint16_t r, g, b; } rgb16;

#undef WARN_UNHANDLED
#undef DEPRECATED
#endif