source: sources/src/graphicsImage.cc @ 1464:3f6711617be1

Revision 1464:3f6711617be1, 15.5 KB checked in by niam, 22 months ago (diff)

{issue #58[resolved]} support for non-c++ exceptions

Line 
1/***************************************************************************
2 *            graphicsImage.cc
3 *
4 *  Thu Nov 23 2007
5 *  Copyright  2007  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef IMAGEMAGICK_EXT
33#ifndef IMAGEMAGICK_PRE_63
34#include <magick/MagickCore.h>
35#else
36#include <magick/ImageMagick.h>
37#endif
38#include <math.h>
39#include <string.h>
40
41#include "graphicsImage.inline"
42
43#include <libdodo/graphicsImage.h>
44#include <libdodo/types.h>
45#include <libdodo/graphicsColor.h>
46#include <libdodo/graphicsImageEx.h>
47#include <libdodo/xexec.h>
48#include <libdodo/ioChannel.h>
49
50namespace dodo {
51    namespace graphics {
52        /**
53         * @class __image_init__
54         * @brief initializes image evironment
55         */
56        class __image_init__ {
57          public:
58
59            /**
60             * contructor
61             */
62            __image_init__();
63
64            /**
65             * destructor
66             */
67            ~__image_init__();
68
69          private:
70
71            /**
72             * ImageMagic error handler
73             * @param et defines error category
74             * @param reason defines the reason of the error
75             * @param description defines description to the reason
76             */
77            static void imErrorHandler(const ExceptionType et,
78                                       const char          *reason,
79                                       const char          *description);
80
81            /**
82             * ImageMagic warning handler
83             * @param et defines warning category
84             * @param reason defines the reason of the warning
85             * @param description defines description to the reason
86             */
87            static void imWarningHandler(const ExceptionType et,
88                                         const char          *reason,
89                                         const char          *description);
90        };
91
92        __image_init__ __image_init_object__;
93    };
94};
95
96using namespace dodo::graphics;
97
98#ifndef GRAPHICS_WO_XEXEC
99image::__collected_data__::__collected_data__(xexec *executor,
100                                              short execObject) : xexec::__collected_data__(executor, execObject),
101                                                                  handle(new __image__)
102{
103}
104#else
105image::__collected_data__::__collected_data__() : handle(new __image__)
106{
107}
108#endif
109
110//-------------------------------------------------------------------
111
112image::__collected_data__::~__collected_data__()
113{
114    delete handle;
115}
116
117//-------------------------------------------------------------------
118
119__image_init__::__image_init__()
120{
121    if (IsMagickInstantiated() == MagickFalse) {
122#ifndef IMAGEMAGICK_PRE_63
123        MagickCoreGenesis(NULL, MagickFalse);
124#else
125        InitializeMagick(NULL);
126#endif
127    }
128
129    SetFatalErrorHandler(imErrorHandler);
130    SetErrorHandler(imErrorHandler);
131    SetWarningHandler(imWarningHandler);
132}
133
134//-------------------------------------------------------------------
135
136__image_init__::~__image_init__()
137{
138    if (IsMagickInstantiated() == MagickTrue) {
139#ifndef IMAGEMAGICK_PRE_63
140        MagickCoreTerminus();
141#else
142        DestroyMagick();
143#endif
144    }
145}
146
147//-------------------------------------------------------------------
148
149void
150__image_init__::imWarningHandler(const ExceptionType,
151                                 const char *,
152                                 const char *)
153{
154}
155
156//-------------------------------------------------------------------
157
158void
159__image_init__::imErrorHandler(const ExceptionType,
160                               const char          *reason,
161                               const char          *description)
162{
163    dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_IMERRORHANDLER, exception::ERRNO_LIBDODO, IMAGEEX_IMERROR, reason ? dodo::string(reason) : __dodostring__, __LINE__, __FILE__, description ? dodo::string(description) : __dodostring__);
164}
165
166//-------------------------------------------------------------------
167
168const char *image::mappingStatements[] = {
169    "RGB",
170    "RGBA",
171};
172
173//-------------------------------------------------------------------
174
175const int image::typeStatements[] = {
176    TrueColorMatteType,
177    GrayscaleMatteType,
178};
179
180//-------------------------------------------------------------------
181
182const int image::pixelSizeStatements[] = {
183    CharPixel,
184    ShortPixel,
185    IntegerPixel,
186    LongPixel,
187    FloatPixel,
188    DoublePixel
189};
190
191//-------------------------------------------------------------------
192
193const char *image::encoderStatements[] = {
194    "PNG",
195    "JPEG",
196    "GIF",
197    "BMP",
198    "XPM",
199    "ICO"
200};
201
202//-------------------------------------------------------------------
203
204const int image::compressionStatements[] = {
205    NoCompression,
206    LZWCompression,
207    RLECompression,
208    ZipCompression,
209    BZipCompression,
210    JPEGCompression,
211    LosslessJPEGCompression,
212    JPEG2000Compression,
213};
214
215//-------------------------------------------------------------------
216
217#ifndef GRAPHICS_WO_XEXEC
218image::image(image &i) : xexec(i),
219                         collectedData(this, OBJECT_GRAPHICSIMAGE)
220#else
221image::image(image &)
222#endif
223{
224}
225
226//-------------------------------------------------------------------
227
228image::image() : exInfo(new ExceptionInfo)
229#ifndef GRAPHICS_WO_XEXEC
230                 ,
231                 collectedData(this, OBJECT_GRAPHICSIMAGE)
232#endif
233{
234#ifndef IMAGEMAGICK_PRE_63
235    collectedData.handle->imInfo = AcquireImageInfo();
236#else
237    collectedData.handle->imInfo = CloneImageInfo(NULL);
238#endif
239}
240
241//-------------------------------------------------------------------
242
243image::~image()
244{
245    if (collectedData.handle->im != NULL)
246        DestroyImage(collectedData.handle->im);
247
248    DestroyImageInfo(collectedData.handle->imInfo);
249    DestroyExceptionInfo((ExceptionInfo *)exInfo);
250
251    delete (ExceptionInfo *)exInfo;
252}
253
254//-------------------------------------------------------------------
255
256void
257image::read(const io::channel &img)
258{
259#ifndef GRAPHICS_WO_XEXEC
260    performPreExec(OPERATION_READ);
261#endif
262
263    GetExceptionInfo((ExceptionInfo *)exInfo);
264    GetImageInfo(collectedData.handle->imInfo);
265
266    if (collectedData.handle->im != NULL)
267        DestroyImage(collectedData.handle->im);
268
269    dodo::string data, dataPart;
270
271    while (true) {
272        dataPart = img.read();
273        if (dataPart.size() == 0)
274            break;
275
276        data += dodo::string(dataPart);
277    }
278    dataPart.clear();
279
280    collectedData.handle->im = BlobToImage(collectedData.handle->imInfo, data.data(), data.size(), (ExceptionInfo *)exInfo);
281    if (collectedData.handle->im == NULL)
282        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_READ, exception::ERRNO_IMAGEMAGICK, ((ExceptionInfo *)exInfo)->error_number, ((ExceptionInfo *)exInfo)->reason, __LINE__, __FILE__, ((ExceptionInfo *)exInfo)->description ? ((ExceptionInfo *)exInfo)->description : __dodostring__);
283
284    collectedData.handle->imInfo->compression = collectedData.handle->im->compression;
285    collectedData.handle->imInfo->quality = collectedData.handle->im->quality;
286
287    strcpy(collectedData.handle->imInfo->magick, collectedData.handle->im->magick);
288
289#ifndef GRAPHICS_WO_XEXEC
290    performPostExec(OPERATION_READ);
291#endif
292}
293
294//-------------------------------------------------------------------
295
296void
297image::create(unsigned long   width,
298              unsigned long   height,
299              const __color__ &background,
300              unsigned short  backgroundDepth)
301{
302#ifndef GRAPHICS_WO_XEXEC
303    performPreExec(OPERATION_CREATE);
304#endif
305
306    GetExceptionInfo((ExceptionInfo *)exInfo);
307    GetImageInfo(collectedData.handle->imInfo);
308
309    if (collectedData.handle->im != NULL)
310        DestroyImage(collectedData.handle->im);
311
312    MagickPixelPacket bg;
313
314    bg.colorspace = RGBColorspace;
315    bg.matte = MagickTrue;
316    bg.fuzz = 0;
317    bg.depth = backgroundDepth;
318
319    bg.red = background.red;
320    bg.green = background.green;
321    bg.blue = background.blue;
322    bg.opacity = background.opacity;
323    bg.index = 0;
324
325    collectedData.handle->im = NewMagickImage(collectedData.handle->imInfo, width, height, &bg);
326    if (collectedData.handle->im == NULL)
327        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_CREATE, exception::ERRNO_IMAGEMAGICK, ((ExceptionInfo *)exInfo)->error_number, ((ExceptionInfo *)exInfo)->reason, __LINE__, __FILE__, ((ExceptionInfo *)exInfo)->description ? ((ExceptionInfo *)exInfo)->description : __dodostring__);
328
329    collectedData.handle->imInfo->compression = collectedData.handle->im->compression;
330    collectedData.handle->imInfo->quality = collectedData.handle->im->quality;
331
332    strcpy(collectedData.handle->imInfo->magick, collectedData.handle->im->magick);
333
334#ifndef GRAPHICS_WO_XEXEC
335    performPostExec(OPERATION_CREATE);
336#endif
337}
338
339//-------------------------------------------------------------------
340
341void
342image::setColorSpecification(short type)
343{
344    if (type < 0 || type >= COLOR_SPECIFICATION_ENUMSIZE)
345        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETTYPE, exception::ERRNO_LIBDODO, IMAGEEX_BADINFO, GRAPHICSIMAGEEX_BADINFO_STR, __LINE__, __FILE__);
346
347    if (collectedData.handle->im == NULL)
348        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETTYPE, exception::ERRNO_IMAGEMAGICK, IMAGEEX_EMPTYIMAGE, GRAPHICSIMAGEEX_EMPTYIMAGE_STR, __LINE__, __FILE__);
349
350    if (SetImageType(collectedData.handle->im, (ImageType)typeStatements[type]) == MagickFalse)
351        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETTYPE, exception::ERRNO_IMAGEMAGICK, IMAGEEX_CANNOTSETCOLORSPECIFICATION, GRAPHICSIMAGEEX_CANNOTSETCOLORSPECIFICATION_STR, __LINE__, __FILE__);
352}
353
354//-------------------------------------------------------------------
355
356void
357image::setAlpha()
358{
359    if (collectedData.handle->im == NULL)
360        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETALPHA, exception::ERRNO_IMAGEMAGICK, IMAGEEX_EMPTYIMAGE, GRAPHICSIMAGEEX_EMPTYIMAGE_STR, __LINE__, __FILE__);
361
362    collectedData.handle->im->matte = MagickTrue;
363}
364
365//-------------------------------------------------------------------
366
367void
368image::removeAlpha()
369{
370    if (collectedData.handle->im == NULL)
371        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_REMOVEALPHA, exception::ERRNO_IMAGEMAGICK, IMAGEEX_EMPTYIMAGE, GRAPHICSIMAGEEX_EMPTYIMAGE_STR, __LINE__, __FILE__);
372
373    collectedData.handle->im->matte = MagickFalse;
374}
375
376//-------------------------------------------------------------------
377
378void
379image::setOpacity(unsigned short opacity)
380{
381    if (collectedData.handle->im == NULL)
382        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETOPACITY, exception::ERRNO_IMAGEMAGICK, IMAGEEX_EMPTYIMAGE, GRAPHICSIMAGEEX_EMPTYIMAGE_STR, __LINE__, __FILE__);
383
384    SetImageOpacity(collectedData.handle->im, opacity);
385}
386
387//-------------------------------------------------------------------
388
389void
390image::setBackgroundColor(__color__ background)
391{
392    if (collectedData.handle->im == NULL)
393        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETBACKGROUNDCOLOR, exception::ERRNO_IMAGEMAGICK, IMAGEEX_EMPTYIMAGE, GRAPHICSIMAGEEX_EMPTYIMAGE_STR, __LINE__, __FILE__);
394
395    collectedData.handle->im->background_color.red = background.red;
396    collectedData.handle->im->background_color.green = background.green;
397    collectedData.handle->im->background_color.blue = background.blue;
398    collectedData.handle->im->background_color.opacity = background.opacity;
399
400    SetImageBackgroundColor(collectedData.handle->im);
401}
402
403//-------------------------------------------------------------------
404
405void
406image::close()
407{
408    if (collectedData.handle->im != NULL) {
409        DestroyImage(collectedData.handle->im);
410
411        collectedData.handle->im = NULL;
412    }
413}
414
415//-------------------------------------------------------------------
416
417void
418image::write(const io::channel &img,
419             short encoder)
420{
421#ifndef GRAPHICS_WO_XEXEC
422    performPreExec(OPERATION_WRITE);
423#endif
424
425    if (collectedData.handle->im == NULL)
426        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_WRITE, exception::ERRNO_IMAGEMAGICK, IMAGEEX_EMPTYIMAGE, GRAPHICSIMAGEEX_EMPTYIMAGE_STR, __LINE__, __FILE__);
427
428    GetExceptionInfo((ExceptionInfo *)exInfo);
429
430    if (encoder < 0 || encoder >= ENCODER_ENUMSIZE)
431        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_WRITE, exception::ERRNO_LIBDODO, IMAGEEX_BADINFO, GRAPHICSIMAGEEX_BADINFO_STR, __LINE__, __FILE__);
432
433    strcpy(collectedData.handle->imInfo->magick, encoderStatements[encoder]);
434
435    size_t size = 0;
436    unsigned char *data = ImageToBlob(collectedData.handle->imInfo, collectedData.handle->im, (size_t *)&size, (ExceptionInfo *)exInfo);
437    if (data == NULL)
438        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_WRITE, exception::ERRNO_IMAGEMAGICK, ((ExceptionInfo *)exInfo)->error_number, ((ExceptionInfo *)exInfo)->reason, __LINE__, __FILE__, ((ExceptionInfo *)exInfo)->description ? ((ExceptionInfo *)exInfo)->description : __dodostring__);
439
440    img.bs = size;
441    img.write(dodo::string((char *)data, size));
442
443#ifndef GRAPHICS_WO_XEXEC
444    performPostExec(OPERATION_WRITE);
445#endif
446}
447
448//-------------------------------------------------------------------
449
450void
451image::setCompression(short type)
452{
453    if (type < 0 || type >= COMPRESSION_ENUMSIZE)
454        dodo_throw exception::basic(exception::MODULE_GRAPHICSIMAGE, IMAGEEX_SETCOMPRESSION, exception::ERRNO_LIBDODO, IMAGEEX_BADINFO, GRAPHICSIMAGEEX_BADINFO_STR, __LINE__, __FILE__);
455
456    collectedData.handle->imInfo->compression = (CompressionType)compressionStatements[type];
457}
458
459//-------------------------------------------------------------------
460
461void
462image::setQuality(short quality)
463{
464    collectedData.handle->imInfo->quality = quality;
465}
466
467//-------------------------------------------------------------------
468
469short
470image::compression()
471{
472    for (int i = 0; i < COMPRESSION_ENUMSIZE; ++i)
473        if (collectedData.handle->imInfo->compression == compressionStatements[i])
474            return i;
475
476    return -1;
477}
478
479//-------------------------------------------------------------------
480
481short
482image::quality()
483{
484    return collectedData.handle->imInfo->quality;
485}
486
487//-------------------------------------------------------------------
488
489short
490image::encoder()
491{
492    for (int i = 0; i < ENCODER_ENUMSIZE; ++i)
493        if (strcmp(collectedData.handle->imInfo->magick, encoderStatements[i]) == 0)
494            return i;
495
496    return -1;
497}
498
499//-------------------------------------------------------------------
500
501image::__size__
502image::imageSize()
503{
504    if (collectedData.handle->im == NULL)
505        return __size__();
506
507    __size__ info;
508
509    info.height = collectedData.handle->im->rows;
510    info.width = collectedData.handle->im->columns;
511
512    return info;
513}
514#endif
515
516//-------------------------------------------------------------------
517
Note: See TracBrowser for help on using the repository browser.