Mercurial > octave-nkf
comparison src/DLD-FUNCTIONS/__magick_read__.cc @ 10295:13d382fc758b
imread: Make reading non-indexed images faster
author | David Grundberg <davidg@cs.umu.se> |
---|---|
date | Wed, 10 Feb 2010 08:41:49 +0100 |
parents | 1a4074e277fe |
children | 2be9b7e71f32 |
comparison
equal
deleted
inserted
replaced
10294:816b91eebe79 | 10295:13d382fc758b |
---|---|
1 /* | 1 /* |
2 | 2 |
3 Copyright (C) 2002, 2009 Andy Adler | 3 Copyright (C) 2002, 2009 Andy Adler |
4 Copyright (C) 2008 Thomas L. Scofield | 4 Copyright (C) 2008 Thomas L. Scofield |
5 Copyright (C) 2010 David Grundberg | |
5 | 6 |
6 This file is part of Octave. | 7 This file is part of Octave. |
7 | 8 |
8 Octave is free software; you can redistribute it and/or modify it | 9 Octave is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 10 under the terms of the GNU General Public License as published by the |
32 #include "ov-struct.h" | 33 #include "ov-struct.h" |
33 | 34 |
34 #ifdef HAVE_MAGICK | 35 #ifdef HAVE_MAGICK |
35 | 36 |
36 #include <Magick++.h> | 37 #include <Magick++.h> |
37 | |
38 unsigned int | |
39 scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth) | |
40 { | |
41 return (static_cast<unsigned int> (static_cast<double> (quantum) | |
42 / MaxRGB * ((1 << depth) - 1))); | |
43 } | |
44 | 38 |
45 octave_value_list | 39 octave_value_list |
46 read_indexed_images (std::vector<Magick::Image>& imvec, | 40 read_indexed_images (std::vector<Magick::Image>& imvec, |
47 const Array<int>& frameidx, bool wantalpha) | 41 const Array<int>& frameidx, bool wantalpha) |
48 { | 42 { |
193 template <class T> | 187 template <class T> |
194 octave_value_list | 188 octave_value_list |
195 read_images (const std::vector<Magick::Image>& imvec, | 189 read_images (const std::vector<Magick::Image>& imvec, |
196 const Array<int>& frameidx, unsigned int depth) | 190 const Array<int>& frameidx, unsigned int depth) |
197 { | 191 { |
192 typedef typename T::element_type P; | |
193 | |
198 octave_value_list retval (3, Matrix ()); | 194 octave_value_list retval (3, Matrix ()); |
199 | 195 |
200 T im; | 196 T im; |
201 | 197 |
202 int rows = imvec[0].baseRows (); | 198 int rows = imvec[0].baseRows (); |
208 idim(0) = rows; | 204 idim(0) = rows; |
209 idim(1) = columns; | 205 idim(1) = columns; |
210 idim(2) = 1; | 206 idim(2) = 1; |
211 idim(3) = nframes; | 207 idim(3) = nframes; |
212 | 208 |
213 Array<int> idx (dim_vector (4)); | |
214 | |
215 Magick::ImageType type = imvec[0].type (); | 209 Magick::ImageType type = imvec[0].type (); |
210 const int divisor = (((1 << QuantumDepth) - 1) / ((1 << depth) - 1)); | |
216 | 211 |
217 switch (type) | 212 switch (type) |
218 { | 213 { |
219 case Magick::BilevelType: | 214 case Magick::BilevelType: |
220 case Magick::GrayscaleType: | 215 case Magick::GrayscaleType: |
221 im = T (idim); | 216 { |
222 for (int frame = 0; frame < nframes; frame++) | 217 im = T (idim); |
223 { | 218 P *vec = im.fortran_vec (); |
224 const Magick::PixelPacket *pix | 219 |
225 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); | 220 for (int frame = 0; frame < nframes; frame++) |
226 | 221 { |
227 int i = 0; | 222 const Magick::PixelPacket *pix |
228 idx(2) = 0; | 223 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); |
229 idx(3) = frame; | 224 |
230 | 225 P *rbuf; |
231 for (int y = 0; y < rows; y++) | 226 rbuf = vec; |
232 { | 227 for (int y = 0; y < rows; y++) |
233 idx(0) = y; | 228 { |
234 for (int x = 0; x < columns; x++) | 229 for (int x = 0; x < columns; x++) |
235 { | 230 { |
236 idx(1) = x; | 231 *rbuf = pix->red / divisor; |
237 im(idx) = scale_quantum_to_depth (pix[i++].red, depth); | 232 pix++; |
238 } | 233 rbuf += rows; |
239 } | 234 } |
235 rbuf -= rows * columns - 1; | |
236 } | |
237 | |
238 // Next frame. | |
239 vec += rows * columns * idim(2); | |
240 } | |
240 } | 241 } |
241 break; | 242 break; |
242 | 243 |
243 case Magick::GrayscaleMatteType: | 244 case Magick::GrayscaleMatteType: |
244 idim(2) = 2; | 245 { |
245 im = T (idim); | 246 idim(2) = 2; |
246 for (int frame = 0; frame < nframes; frame++) | 247 im = T (idim); |
247 { | 248 P *vec = im.fortran_vec (); |
248 const Magick::PixelPacket *pix | 249 |
249 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); | 250 for (int frame = 0; frame < nframes; frame++) |
250 | 251 { |
251 int i = 0; | 252 const Magick::PixelPacket *pix |
252 idx(3) = frame; | 253 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); |
253 | 254 |
254 for (int y = 0; y < rows; y++) | 255 P *rbuf, *obuf; |
255 { | 256 rbuf = vec; |
256 idx(0) = y; | 257 obuf = vec + rows * columns; |
257 for (int x = 0; x < columns; x++) | 258 for (int y = 0; y < rows; y++) |
258 { | 259 { |
259 idx(1) = x; | 260 for (int x = 0; x < columns; x++) |
260 idx(2) = 0; | 261 { |
261 im(idx) = scale_quantum_to_depth (pix[i].red, depth); | 262 *rbuf = pix->red / divisor; |
262 idx(2) = 1; | 263 *obuf = pix->opacity / divisor; |
263 im(idx) = scale_quantum_to_depth (pix[i].opacity, depth); | 264 pix++; |
264 i++; | 265 rbuf += rows; |
265 } | 266 obuf += rows; |
266 } | 267 } |
268 rbuf -= rows * columns - 1; | |
269 obuf -= rows * columns - 1; | |
270 } | |
271 | |
272 // Next frame. | |
273 vec += rows * columns * idim(2); | |
274 } | |
267 } | 275 } |
268 break; | 276 break; |
269 | 277 |
270 case Magick::PaletteType: | 278 case Magick::PaletteType: |
271 case Magick::TrueColorType: | 279 case Magick::TrueColorType: |
272 idim(2) = 3; | 280 { |
273 im = T (idim); | 281 idim(2) = 3; |
274 for (int frame = 0; frame < nframes; frame++) | 282 im = T (idim); |
275 { | 283 P *vec = im.fortran_vec (); |
276 const Magick::PixelPacket *pix | 284 |
277 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); | 285 for (int frame = 0; frame < nframes; frame++) |
278 | 286 { |
279 int i = 0; | 287 const Magick::PixelPacket *pix |
280 idx(3) = frame; | 288 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); |
281 | 289 |
282 for (int y = 0; y < rows; y++) | 290 P *rbuf, *gbuf, *bbuf; |
283 { | 291 rbuf = vec; |
284 idx(0) = y; | 292 gbuf = vec + rows * columns; |
285 for (int x = 0; x < columns; x++) | 293 bbuf = vec + rows * columns * 2; |
286 { | 294 for (int y = 0; y < rows; y++) |
287 idx(1) = x; | 295 { |
288 idx(2) = 0; | 296 for (int x = 0; x < columns; x++) |
289 im(idx) = scale_quantum_to_depth (pix[i].red, depth); | 297 { |
290 idx(2) = 1; | 298 *rbuf = pix->red / divisor; |
291 im(idx) = scale_quantum_to_depth (pix[i].green, depth); | 299 *gbuf = pix->green / divisor; |
292 idx(2) = 2; | 300 *bbuf = pix->blue / divisor; |
293 im(idx) = scale_quantum_to_depth (pix[i].blue, depth); | 301 pix++; |
294 i++; | 302 rbuf += rows; |
295 } | 303 gbuf += rows; |
296 } | 304 bbuf += rows; |
305 } | |
306 rbuf -= rows * columns - 1; | |
307 gbuf -= rows * columns - 1; | |
308 bbuf -= rows * columns - 1; | |
309 } | |
310 | |
311 // Next frame. | |
312 vec += rows * columns * idim(2); | |
313 } | |
297 } | 314 } |
298 break; | 315 break; |
299 | 316 |
300 case Magick::PaletteMatteType: | 317 case Magick::PaletteMatteType: |
301 case Magick::TrueColorMatteType: | 318 case Magick::TrueColorMatteType: |
302 case Magick::ColorSeparationType: | 319 case Magick::ColorSeparationType: |
303 idim(2) = 4; | 320 { |
304 im = T (idim); | 321 idim(2) = 4; |
305 for (int frame = 0; frame < nframes; frame++) | 322 im = T (idim); |
306 { | 323 P *vec = im.fortran_vec (); |
307 const Magick::PixelPacket *pix | 324 |
308 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); | 325 for (int frame = 0; frame < nframes; frame++) |
309 | 326 { |
310 int i = 0; | 327 const Magick::PixelPacket *pix |
311 idx(3) = frame; | 328 = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); |
312 | 329 |
313 for (int y = 0; y < rows; y++) | 330 P *rbuf, *gbuf, *bbuf, *obuf; |
314 { | 331 rbuf = vec; |
315 idx(0) = y; | 332 gbuf = vec + rows * columns; |
316 for (int x = 0; x < columns; x++) | 333 bbuf = vec + rows * columns * 2; |
317 { | 334 obuf = vec + rows * columns * 3; |
318 idx(1) = x; | 335 for (int y = 0; y < rows; y++) |
319 idx(2) = 0; | 336 { |
320 im(idx) = scale_quantum_to_depth (pix[i].red, depth); | 337 for (int x = 0; x < columns; x++) |
321 idx(2) = 1; | 338 { |
322 im(idx) = scale_quantum_to_depth (pix[i].green, depth); | 339 *rbuf = pix->red / divisor; |
323 idx(2) = 2; | 340 *gbuf = pix->green / divisor; |
324 im(idx) = scale_quantum_to_depth (pix[i].blue, depth); | 341 *bbuf = pix->blue / divisor; |
325 idx(2) = 3; | 342 *obuf = pix->opacity / divisor; |
326 im(idx) = scale_quantum_to_depth (pix[i].opacity, depth); | 343 pix++; |
327 i++; | 344 rbuf += rows; |
328 } | 345 gbuf += rows; |
329 } | 346 bbuf += rows; |
347 obuf += rows; | |
348 } | |
349 rbuf -= rows * columns - 1; | |
350 gbuf -= rows * columns - 1; | |
351 bbuf -= rows * columns - 1; | |
352 obuf -= rows * columns - 1; | |
353 } | |
354 | |
355 // Next frame. | |
356 vec += rows * columns * idim(2); | |
357 } | |
330 } | 358 } |
331 break; | 359 break; |
332 | 360 |
333 default: | 361 default: |
334 error ("__magick_read__: undefined ImageMagick image type"); | 362 error ("__magick_read__: undefined ImageMagick image type"); |