summaryrefslogtreecommitdiff
path: root/noncore/multimedia/camera2/image.cpp
Unidiff
Diffstat (limited to 'noncore/multimedia/camera2/image.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/camera2/image.cpp239
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*/
49QImage 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//
123QSize 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
147QImage 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
194QImage 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//
210QSize
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