20130313
[gdash.git] / src / gfx / pixbuffactory.cpp
blob7ed30ee9dd5b600144bad57f59ee258a237a7e08
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <glib/gi18n.h>
19 #include "gfx/pixbuf.hpp"
20 #include "gfx/pixbuffactory.hpp"
21 #include "gfx/pixbufmanip.hpp"
23 /* names of scaling types supported. */
24 /* scale2x and scale3x are not translated: the license says that we should call it in its original name. */
25 const char *gd_scaling_name[]={N_("Original"), N_("2x nearest"), "Scale2x", "HQ2x", N_("3x nearest"), "Scale3x", "HQ3x", N_("4x nearest"), "Scale4x", "HQ4x", NULL};
26 /* scaling factors of scaling types supported. */
27 const int gd_scaling_scale[]={1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
29 /* check the arrays on start */
30 static class _init {
31 public:
32 _init() {
33 g_assert(G_N_ELEMENTS(gd_scaling_name)==GD_SCALING_MAX+1); /* +1 is the terminating NULL */
34 g_assert(G_N_ELEMENTS(gd_scaling_scale)==GD_SCALING_MAX);
36 } _init;
38 /* scales a pixbuf with the appropriate scaling type. */
39 Pixbuf *PixbufFactory::create_scaled(const Pixbuf &src) const
41 int gd_scale=gd_scaling_scale[scaling_type];
42 Pixbuf *scaled=this->create(src.get_width()*gd_scale, src.get_height()*gd_scale);
44 switch (scaling_type) {
45 case GD_SCALING_MAX:
46 /* not a valid case, but to avoid compiler warning */
47 g_assert_not_reached();
48 break;
50 case GD_SCALING_ORIGINAL:
51 src.copy(*scaled, 0, 0);
52 break;
53 case GD_SCALING_2X:
54 scale2xnearest(src, *scaled);
55 break;
56 case GD_SCALING_2X_SCALE2X:
57 scale2x(src, *scaled);
58 break;
59 case GD_SCALING_2X_HQ2X:
60 hq2x(src, *scaled);
61 break;
62 case GD_SCALING_3X:
63 scale3xnearest(src, *scaled);
64 break;
65 case GD_SCALING_3X_SCALE3X:
66 scale3x(src, *scaled);
67 break;
68 case GD_SCALING_3X_HQ3X:
69 hq3x(src, *scaled);
70 break;
71 case GD_SCALING_4X:
73 Pixbuf *scale2x=this->create(src.get_width()*2, src.get_height()*2);
74 scale2xnearest(src, *scale2x);
75 scale2xnearest(*scale2x, *scaled);
76 delete scale2x;
78 break;
79 case GD_SCALING_4X_SCALE4X:
80 /* scale2x applied twice. */
82 Pixbuf *scale2xpb=this->create(src.get_width()*2, src.get_height()*2);
83 scale2x(src, *scale2xpb);
84 scale2x(*scale2xpb, *scaled);
85 delete scale2xpb;
87 break;
88 case GD_SCALING_4X_HQ4X:
89 hq4x(src, *scaled);
90 break;
93 if (pal_emulation)
94 pal_emulate(*scaled);
96 return scaled;
99 PixbufFactory::PixbufFactory(GdScalingType scaling_type_, bool pal_emulation_)
101 scaling_type(scaling_type_),
102 pal_emulation(pal_emulation_)
106 int PixbufFactory::get_pixmap_scale() const
108 return gd_scaling_scale[scaling_type];
111 void PixbufFactory::set_properties(GdScalingType scaling_type_, bool pal_emulation_)
113 scaling_type=scaling_type_;
114 pal_emulation=pal_emulation_;
117 Pixbuf *PixbufFactory::create_from_base64(const char *base64) const
119 gsize len;
120 guchar *decoded=g_base64_decode(base64, &len);
121 // creating the pixbuf might fail, in that case, also free memory
122 try {
123 Pixbuf *pix=create_from_inline(len, decoded);
124 delete decoded;
125 return pix;
126 } catch (...) {
127 delete decoded;
128 throw;