Diffstat (limited to 'noncore/multimedia/camera2/image.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/multimedia/camera2/image.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/noncore/multimedia/camera2/image.cpp b/noncore/multimedia/camera2/image.cpp new file mode 100644 index 0000000..39b6d8b --- a/dev/null +++ b/noncore/multimedia/camera2/image.cpp | |||
@@ -0,0 +1,239 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000-2006 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of the Qtopia Environment. | ||
5 | ** | ||
6 | ** This program is free software; you can redistribute it and/or modify it | ||
7 | ** under the terms of the GNU General Public License as published by the | ||
8 | ** Free Software Foundation; either version 2 of the License, or (at your | ||
9 | ** option) any later version. | ||
10 | ** | ||
11 | ** A copy of the GNU GPL license version 2 is included in this package as | ||
12 | ** LICENSE.GPL. | ||
13 | ** | ||
14 | ** This program is distributed in the hope that it will be useful, but | ||
15 | ** WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | ** See the GNU General Public License for more details. | ||
18 | ** | ||
19 | ** In addition, as a special exception Trolltech gives permission to link | ||
20 | ** the code of this program with Qtopia applications copyrighted, developed | ||
21 | ** and distributed by Trolltech under the terms of the Qtopia Personal Use | ||
22 | ** License Agreement. You must comply with the GNU General Public License | ||
23 | ** in all respects for all of the code used other than the applications | ||
24 | ** licensed under the Qtopia Personal Use License Agreement. If you modify | ||
25 | ** this file, you may extend this exception to your version of the file, | ||
26 | ** but you are not obligated to do so. If you do not wish to do so, delete | ||
27 | ** this exception statement from your version. | ||
28 | ** | ||
29 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
30 | ** | ||
31 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
32 | ** not clear to you. | ||
33 | ** | ||
34 | **********************************************************************/ | ||
35 | |||
36 | #include "image.h" | ||
37 | |||
38 | #include <qfileinfo.h> | ||
39 | #include <qimage.h> | ||
40 | #include <qstring.h> | ||
41 | |||
42 | /*! | ||
43 | Returns an image created by loading the \a filename, | ||
44 | and scalining it, preserving aspect ratio, to fit in | ||
45 | \a width by \a height pixels. | ||
46 | |||
47 | First availability: Qtopia 2.0 | ||
48 | */ | ||
49 | QImage Image::loadScaled(const QString & filename, const int width, const int height, | ||
50 | ScaleMode mode) | ||
51 | { | ||
52 | QImageIO iio; | ||
53 | QString param; | ||
54 | int w = width; | ||
55 | int h = height; | ||
56 | |||
57 | if (width == 0 || height == 0) | ||
58 | return QImage(); | ||
59 | |||
60 | iio.setFileName(filename); | ||
61 | |||
62 | // | ||
63 | // Try and load and scale the image in one hit. | ||
64 | // | ||
65 | param.sprintf("GetHeaderInformation"); | ||
66 | iio.setParameters(param); | ||
67 | iio.read(); | ||
68 | |||
69 | // | ||
70 | // If we don't have bits(), read() understands parameters, | ||
71 | // and we can setup for fast reading. Otherwise, take the | ||
72 | // performance hit and do things slowly. | ||
73 | // | ||
74 | if (!iio.image().bits()) { | ||
75 | if ((iio.image().width() < w) && (iio.image().height() < h)) { | ||
76 | param.sprintf("%s", "Fast"); // No Tr | ||
77 | } | ||
78 | else { | ||
79 | int shrink_factor = 1; | ||
80 | QString smode; | ||
81 | switch (mode) { | ||
82 | case ScaleMin: | ||
83 | smode = "ScaleMin"; | ||
84 | shrink_factor = QMAX(iio.image().width() / w, iio.image().height() / h); | ||
85 | break; | ||
86 | case ScaleMax: | ||
87 | smode = "ScaleMax"; | ||
88 | shrink_factor = QMIN(iio.image().width() / w, iio.image().height() / h); | ||
89 | break; | ||
90 | case ScaleFree: | ||
91 | smode = "ScaleFree"; | ||
92 | shrink_factor = QMIN(iio.image().width() / w, iio.image().height() / h); | ||
93 | break; | ||
94 | } | ||
95 | param.sprintf("Scale( %i, %i, %s )%s, Shrink( %i )", // No tr | ||
96 | w, h, smode.latin1(), ", Fast", shrink_factor); // No tr | ||
97 | } | ||
98 | |||
99 | iio.setParameters(param); | ||
100 | iio.read(); | ||
101 | return iio.image(); | ||
102 | } | ||
103 | |||
104 | if ((iio.image().width() > w) || (iio.image().height() > h)) { | ||
105 | QSize s = aspectScaleSize(iio.image().width(), iio.image().height(), w, h, mode); | ||
106 | return iio.image().smoothScale(s.width(), s.height()); | ||
107 | } | ||
108 | |||
109 | return iio.image(); | ||
110 | } | ||
111 | |||
112 | // | ||
113 | // Returns new size of image, scaled to target_width and target_height, | ||
114 | // whilst preserving aspect ratio. Useful when it's not possible to | ||
115 | // scale an image prior to using it (eg. using RichText). Should be in | ||
116 | // global image utils. | ||
117 | // | ||
118 | // NOTE | ||
119 | // - expensive for images whose drivers do not allow us to retrieve | ||
120 | // parameters without reading the entire image. Currently (20030930) | ||
121 | // only the jpeg driver allows parameter reading. | ||
122 | // | ||
123 | QSize Image::loadScaledImageSize(const QString & filename, int target_width, int target_height, | ||
124 | int maxscale, ScaleMode mode) | ||
125 | { | ||
126 | QImageIO iio; | ||
127 | iio.setFileName(filename); | ||
128 | iio.setParameters("GetHeaderInformation"); | ||
129 | iio.read(); | ||
130 | |||
131 | int w = iio.image().width(); | ||
132 | int h = iio.image().height(); | ||
133 | |||
134 | // | ||
135 | // Scaling up small pictures can be very ugly. | ||
136 | // Leave them alone if they are too small. | ||
137 | // | ||
138 | if (maxscale && w * maxscale < target_width && h * maxscale < target_height) | ||
139 | return QSize(w * maxscale, h * maxscale); | ||
140 | |||
141 | return aspectScaleSize(w, h, target_width, target_height, mode); | ||
142 | } | ||
143 | |||
144 | // Load an image to be used as a portrait. Force its height to height, | ||
145 | // scale width to new height, and crop the width if it's still > width | ||
146 | // XXX : Should be using integer math | ||
147 | QImage Image::loadPortrait(const QString & filename, const int width, const int height) | ||
148 | { | ||
149 | QImageIO iio; | ||
150 | QString param; | ||
151 | int w = width; | ||
152 | int h = height; | ||
153 | |||
154 | if (width == 0 || height == 0) | ||
155 | return QImage(); | ||
156 | |||
157 | iio.setFileName(filename); | ||
158 | |||
159 | // | ||
160 | // Try and load and scale the image in one hit. | ||
161 | // | ||
162 | param.sprintf("GetHeaderInformation"); | ||
163 | iio.setParameters(param); | ||
164 | iio.read(); | ||
165 | |||
166 | // | ||
167 | // If we don't have bits(), read() understands parameters, | ||
168 | // and we can setup for fast reading. Otherwise, take the | ||
169 | // performance hit and do things slowly. | ||
170 | // | ||
171 | if (!iio.image().bits()) { | ||
172 | |||
173 | w = (int) ((double) iio.image().width() / (double) (iio.image().height()) * | ||
174 | (double) height); | ||
175 | param.sprintf("Scale( %i, %i, ScaleFree )%s", // No tr | ||
176 | w, h, ", Fast"); // No tr | ||
177 | |||
178 | iio.setParameters(param); | ||
179 | iio.read(); | ||
180 | |||
181 | if (w > width) { | ||
182 | int x = (int) ((double) (w - width) / 2); | ||
183 | QRect r(x, 0, width, height); | ||
184 | return iio.image().copy(r); | ||
185 | } | ||
186 | else | ||
187 | return iio.image(); | ||
188 | } | ||
189 | else | ||
190 | //scale width to the new height | ||
191 | return sizeToPortrait(iio.image(), width, height); | ||
192 | } | ||
193 | |||
194 | QImage Image::sizeToPortrait(const QImage & image, const int width, const int height) | ||
195 | { | ||
196 | int w = (image.width() * height) / image.height(); | ||
197 | if (w > width) { | ||
198 | int x = (w - width) / 2; | ||
199 | QRect r(x, 0, width, height); | ||
200 | return image.smoothScale(w, height).copy(r); | ||
201 | } | ||
202 | else | ||
203 | return image.smoothScale(width, height); | ||
204 | } | ||
205 | |||
206 | // | ||
207 | // Return (w x h) scaled to (target_width x target_height) with aspect | ||
208 | // ratio preserved. | ||
209 | // | ||
210 | QSize | ||
211 | Image::aspectScaleSize(const int w, const int h, const int target_width, | ||
212 | const int target_height, ScaleMode mode) | ||
213 | { | ||
214 | QSize s; | ||
215 | if (mode == ScaleFree) { | ||
216 | s = QSize(target_width, target_height); | ||
217 | } | ||
218 | else { | ||
219 | bool useHeight = TRUE; | ||
220 | int rw = target_height * w / h; | ||
221 | |||
222 | if (mode == ScaleMin) { | ||
223 | useHeight = (rw <= target_width); | ||
224 | } | ||
225 | else { // mode == ScaleMax | ||
226 | useHeight = (rw >= target_width); | ||
227 | } | ||
228 | |||
229 | if (useHeight) { | ||
230 | s = QSize(rw, target_height); | ||
231 | } | ||
232 | else { | ||
233 | s = QSize(target_width, target_width * h / w); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | return s; | ||
238 | } | ||
239 | |||