[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: reading jpegs faster
From: |
David Grundberg |
Subject: |
Re: reading jpegs faster |
Date: |
Mon, 08 Feb 2010 11:21:28 +0100 |
User-agent: |
Thunderbird 2.0.0.23 (X11/20090812) |
David Grundberg wrote:
John W. Eaton wrote:
On 22-Jan-2010, David Grundberg wrote:
| Okay. Now I got it down to 1.3 seconds. That's 130% compared to the
| jpgread performance, instead of the previous 900%. Needs polish,
but it | works.
Thanks for looking at this problem.
| + P *vec = reinterpret_cast<P *> (im.fortran_vec ());
I don't think this cast is needed, given that P appears to always be
the same as the element type of IM. So you could use the element_type
typedef from the class T and eliminate the template parameter P:
template <class T, unsigned int D>
octave_value_list
read_images (const std::vector<Magick::Image>& imvec,
const Array<int>& frameidx, unsigned int depth)
{
octave_value_list retval (3, Matrix ());
T im;
typedef typename T::element_type P;
...
P *vec = im.fortran_vec ();
...
case 1:
output = read_images<boolNDArray, 1> (imvec, frameidx,
depth);
break;
...
jwe
Thanks for the hint. I've been thinking on how to do that.
David
The attached changeset implements fortran_vec pointer arithmetics for
all non-paletted images.
David
# HG changeset patch
# User David Grundberg <address@hidden>
# Date 1265623865 -3600
# Node ID ae93309f3d8896c7beb04cdd4ed4a83a32a6a1da
# Parent 272179888089ab8ce3c36139c6d474c67aae1e02
imread: Make reading non-indexed images faster
diff -r 272179888089 -r ae93309f3d88 src/ChangeLog
--- a/src/ChangeLog Mon Feb 08 01:36:18 2010 -0500
+++ b/src/ChangeLog Mon Feb 08 11:11:05 2010 +0100
@@ -1,3 +1,11 @@
+2010-02-08 David Grundberg <address@hidden>
+
+ * DLD-FUNCTIONS/__magick_read__.cc (read_images): Reimplement
+ copying with direct fortran_vec manipulation, avoiding indexing
+ operations. Replace scale_quantum_to_depth calls with simple
+ arithmetics.
+ (scale_quantum_to_depth): Remove function.
+
2010-02-08 John W. Eaton <address@hidden>
* ov-class.cc (Fclass): If more than 1 argument, check that
diff -r 272179888089 -r ae93309f3d88 src/DLD-FUNCTIONS/__magick_read__.cc
--- a/src/DLD-FUNCTIONS/__magick_read__.cc Mon Feb 08 01:36:18 2010 -0500
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc Mon Feb 08 11:11:05 2010 +0100
@@ -2,6 +2,7 @@
Copyright (C) 2002, 2009 Andy Adler
Copyright (C) 2008 Thomas L. Scofield
+Copyright (C) 2010 David Grundberg
This file is part of Octave.
@@ -34,13 +35,6 @@
#ifdef HAVE_MAGICK
#include <Magick++.h>
-
-unsigned int
-scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
-{
- return (static_cast<unsigned int> (static_cast<double> (quantum)
- / MaxRGB * ((1 << depth) - 1)));
-}
octave_value_list
read_indexed_images (std::vector<Magick::Image>& imvec,
@@ -195,6 +189,8 @@
read_images (const std::vector<Magick::Image>& imvec,
const Array<int>& frameidx, unsigned int depth)
{
+ typedef typename T::element_type P;
+
octave_value_list retval (3, Matrix ());
T im;
@@ -210,123 +206,155 @@
idim(2) = 1;
idim(3) = nframes;
- Array<int> idx (dim_vector (4));
-
Magick::ImageType type = imvec[0].type ();
+ const int divisor = (((1 << QuantumDepth) - 1) / ((1 << depth) - 1));
switch (type)
{
case Magick::BilevelType:
case Magick::GrayscaleType:
- im = T (idim);
- for (int frame = 0; frame < nframes; frame++)
- {
- const Magick::PixelPacket *pix
- = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+ {
+ im = T (idim);
+ P *vec = im.fortran_vec ();
- int i = 0;
- idx(2) = 0;
- idx(3) = frame;
+ for (int frame = 0; frame < nframes; frame++)
+ {
+ const Magick::PixelPacket *pix
+ = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
- for (int y = 0; y < rows; y++)
- {
- idx(0) = y;
- for (int x = 0; x < columns; x++)
- {
- idx(1) = x;
- im(idx) = scale_quantum_to_depth (pix[i++].red, depth);
- }
- }
+ P *rbuf;
+ rbuf = vec;
+ for (int y = 0; y < rows; y++)
+ {
+ for (int x = 0; x < columns; x++)
+ {
+ *rbuf = pix->red / divisor;
+ pix++;
+ rbuf += rows;
+ }
+ rbuf -= rows * columns - 1;
+ }
+
+ // Next frame.
+ vec += rows * columns * idim(2);
+ }
}
break;
case Magick::GrayscaleMatteType:
- idim(2) = 2;
- im = T (idim);
- for (int frame = 0; frame < nframes; frame++)
- {
- const Magick::PixelPacket *pix
- = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+ {
+ idim(2) = 2;
+ im = T (idim);
+ P *vec = im.fortran_vec ();
- int i = 0;
- idx(3) = frame;
+ for (int frame = 0; frame < nframes; frame++)
+ {
+ const Magick::PixelPacket *pix
+ = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
- for (int y = 0; y < rows; y++)
- {
- idx(0) = y;
- for (int x = 0; x < columns; x++)
- {
- idx(1) = x;
- idx(2) = 0;
- im(idx) = scale_quantum_to_depth (pix[i].red, depth);
- idx(2) = 1;
- im(idx) = scale_quantum_to_depth (pix[i].opacity, depth);
- i++;
- }
- }
+ P *rbuf, *obuf;
+ rbuf = vec;
+ obuf = vec + rows * columns;
+ for (int y = 0; y < rows; y++)
+ {
+ for (int x = 0; x < columns; x++)
+ {
+ *rbuf = pix->red / divisor;
+ *obuf = pix->opacity / divisor;
+ pix++;
+ rbuf += rows;
+ obuf += rows;
+ }
+ rbuf -= rows * columns - 1;
+ obuf -= rows * columns - 1;
+ }
+
+ // Next frame.
+ vec += rows * columns * idim(2);
+ }
}
break;
case Magick::PaletteType:
case Magick::TrueColorType:
- idim(2) = 3;
- im = T (idim);
- for (int frame = 0; frame < nframes; frame++)
- {
- const Magick::PixelPacket *pix
- = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+ {
+ idim(2) = 3;
+ im = T (idim);
+ P *vec = im.fortran_vec ();
- int i = 0;
- idx(3) = frame;
+ for (int frame = 0; frame < nframes; frame++)
+ {
+ const Magick::PixelPacket *pix
+ = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
- for (int y = 0; y < rows; y++)
- {
- idx(0) = y;
- for (int x = 0; x < columns; x++)
- {
- idx(1) = x;
- idx(2) = 0;
- im(idx) = scale_quantum_to_depth (pix[i].red, depth);
- idx(2) = 1;
- im(idx) = scale_quantum_to_depth (pix[i].green, depth);
- idx(2) = 2;
- im(idx) = scale_quantum_to_depth (pix[i].blue, depth);
- i++;
- }
- }
+ P *rbuf, *gbuf, *bbuf;
+ rbuf = vec;
+ gbuf = vec + rows * columns;
+ bbuf = vec + rows * columns * 2;
+ for (int y = 0; y < rows; y++)
+ {
+ for (int x = 0; x < columns; x++)
+ {
+ *rbuf = pix->red / divisor;
+ *gbuf = pix->green / divisor;
+ *bbuf = pix->blue / divisor;
+ pix++;
+ rbuf += rows;
+ gbuf += rows;
+ bbuf += rows;
+ }
+ rbuf -= rows * columns - 1;
+ gbuf -= rows * columns - 1;
+ bbuf -= rows * columns - 1;
+ }
+
+ // Next frame.
+ vec += rows * columns * idim(2);
+ }
}
break;
case Magick::PaletteMatteType:
case Magick::TrueColorMatteType:
case Magick::ColorSeparationType:
- idim(2) = 4;
- im = T (idim);
- for (int frame = 0; frame < nframes; frame++)
- {
- const Magick::PixelPacket *pix
- = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+ {
+ idim(2) = 4;
+ im = T (idim);
+ P *vec = im.fortran_vec ();
- int i = 0;
- idx(3) = frame;
+ for (int frame = 0; frame < nframes; frame++)
+ {
+ const Magick::PixelPacket *pix
+ = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
- for (int y = 0; y < rows; y++)
- {
- idx(0) = y;
- for (int x = 0; x < columns; x++)
- {
- idx(1) = x;
- idx(2) = 0;
- im(idx) = scale_quantum_to_depth (pix[i].red, depth);
- idx(2) = 1;
- im(idx) = scale_quantum_to_depth (pix[i].green, depth);
- idx(2) = 2;
- im(idx) = scale_quantum_to_depth (pix[i].blue, depth);
- idx(2) = 3;
- im(idx) = scale_quantum_to_depth (pix[i].opacity, depth);
- i++;
- }
- }
+ P *rbuf, *gbuf, *bbuf, *obuf;
+ rbuf = vec;
+ gbuf = vec + rows * columns;
+ bbuf = vec + rows * columns * 2;
+ obuf = vec + rows * columns * 3;
+ for (int y = 0; y < rows; y++)
+ {
+ for (int x = 0; x < columns; x++)
+ {
+ *rbuf = pix->red / divisor;
+ *gbuf = pix->green / divisor;
+ *bbuf = pix->blue / divisor;
+ *obuf = pix->opacity / divisor;
+ pix++;
+ rbuf += rows;
+ gbuf += rows;
+ bbuf += rows;
+ obuf += rows;
+ }
+ rbuf -= rows * columns - 1;
+ gbuf -= rows * columns - 1;
+ bbuf -= rows * columns - 1;
+ obuf -= rows * columns - 1;
+ }
+
+ // Next frame.
+ vec += rows * columns * idim(2);
+ }
}
break;
- Re: reading jpegs faster,
David Grundberg <=