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");