Mercurial > hg > octave-nkf
diff libinterp/dldfcn/__magick_read__.cc @ 18610:30aa4e85f8d5 stable
Fix writing and reading of multipage images.
* __magick_read__.cc (encode_uint_image): reset the coordinates for each
Magick::Image object so that writing of multipage images (matrices with
non-singleton 4th dimension) work properly. Stride over the extra channels
at the end of each page, to fix writing of multipage RGB and CMYK images.
(read_images): correct stride over each frame for RGB and CMYK images.
* imwrite.m: add tests to write and read multipage grayscale and RGB images.
Reduce size of test images to speed up comparison.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Tue, 04 Mar 2014 16:52:00 +0000 |
parents | bc1809fe55e4 |
children | e0cc67d5a462 |
line wrap: on
line diff
--- a/libinterp/dldfcn/__magick_read__.cc +++ b/libinterp/dldfcn/__magick_read__.cc @@ -416,6 +416,7 @@ } } + const octave_idx_type colour_stride = nRows * nCols; switch (type) { case Magick::BilevelType: // Monochrome bi-level image @@ -480,6 +481,7 @@ img = T (dim_vector (nRows, nCols, 3, nFrames)); P *img_fvec = img.fortran_vec (); + const octave_idx_type frame_stride = colour_stride * 3; for (octave_idx_type frame = 0; frame < nFrames; frame++) { const Magick::PixelPacket *pix @@ -487,10 +489,9 @@ col_cache, row_cache); octave_idx_type idx = 0; - img_fvec += nRows * nCols * frame; P *rbuf = img_fvec; - P *gbuf = img_fvec + nRows * nCols; - P *bbuf = img_fvec + nRows * nCols * 2; + P *gbuf = img_fvec + colour_stride; + P *bbuf = img_fvec + colour_stride * 2; for (octave_idx_type col = 0; col < nCols; col++) { @@ -504,6 +505,7 @@ } pix -= col_shift; } + img_fvec += frame_stride; } break; } @@ -516,6 +518,8 @@ P *img_fvec = img.fortran_vec (); P *a_fvec = alpha.fortran_vec (); + const octave_idx_type frame_stride = colour_stride * 3; + // Unlike the index for the other channels, this one won't need // to be reset on each frame since it's a separate matrix. octave_idx_type a_idx = 0; @@ -526,10 +530,9 @@ col_cache, row_cache); octave_idx_type idx = 0; - img_fvec += nRows * nCols * frame; P *rbuf = img_fvec; - P *gbuf = img_fvec + nRows * nCols; - P *bbuf = img_fvec + nRows * nCols * 2; + P *gbuf = img_fvec + colour_stride; + P *bbuf = img_fvec + colour_stride * 2; for (octave_idx_type col = 0; col < nCols; col++) { @@ -544,6 +547,7 @@ } pix -= col_shift; } + img_fvec += frame_stride; } retval(2) = alpha; break; @@ -554,6 +558,7 @@ img = T (dim_vector (nRows, nCols, 4, nFrames)); P *img_fvec = img.fortran_vec (); + const octave_idx_type frame_stride = colour_stride * 4; for (octave_idx_type frame = 0; frame < nFrames; frame++) { const Magick::PixelPacket *pix @@ -561,11 +566,10 @@ col_cache, row_cache); octave_idx_type idx = 0; - img_fvec += nRows * nCols * frame; P *cbuf = img_fvec; - P *mbuf = img_fvec + nRows * nCols; - P *ybuf = img_fvec + nRows * nCols * 2; - P *kbuf = img_fvec + nRows * nCols * 3; + P *mbuf = img_fvec + colour_stride; + P *ybuf = img_fvec + colour_stride * 2; + P *kbuf = img_fvec + colour_stride * 3; for (octave_idx_type col = 0; col < nCols; col++) { @@ -580,6 +584,7 @@ } pix -= col_shift; } + img_fvec += frame_stride; } break; } @@ -592,6 +597,8 @@ P *img_fvec = img.fortran_vec (); P *a_fvec = alpha.fortran_vec (); + const octave_idx_type frame_stride = colour_stride * 4; + // Unlike the index for the other channels, this one won't need // to be reset on each frame since it's a separate matrix. octave_idx_type a_idx = 0; @@ -606,11 +613,10 @@ = imvec[frameidx(frame)].getConstIndexes (); octave_idx_type idx = 0; - img_fvec += nRows * nCols * frame; P *cbuf = img_fvec; - P *mbuf = img_fvec + nRows * nCols; - P *ybuf = img_fvec + nRows * nCols * 2; - P *kbuf = img_fvec + nRows * nCols * 3; + P *mbuf = img_fvec + colour_stride; + P *ybuf = img_fvec + colour_stride * 2; + P *kbuf = img_fvec + colour_stride * 3; for (octave_idx_type col = 0; col < nCols; col++) { @@ -626,6 +632,7 @@ } pix -= col_shift; } + img_fvec += frame_stride; } retval(2) = alpha; break; @@ -1062,7 +1069,6 @@ { case Magick::GrayscaleType: { - octave_idx_type GM_idx = 0; for (octave_idx_type frame = 0; frame < nFrames; frame++) { Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, @@ -1070,6 +1076,7 @@ Magick::DirectClass); Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + octave_idx_type GM_idx = 0; for (octave_idx_type col = 0; col < nCols; col++) { for (octave_idx_type row = 0; row < nRows; row++) @@ -1091,7 +1098,6 @@ case Magick::GrayscaleMatteType: { - octave_idx_type GM_idx = 0; for (octave_idx_type frame = 0; frame < nFrames; frame++) { Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, @@ -1099,6 +1105,7 @@ Magick::DirectClass); Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + octave_idx_type GM_idx = 0; for (octave_idx_type col = 0; col < nCols; col++) { for (octave_idx_type row = 0; row < nRows; row++) @@ -1125,7 +1132,6 @@ // The fortran_vec offset for the green and blue channels const octave_idx_type G_offset = nCols * nRows; const octave_idx_type B_offset = nCols * nRows * 2; - octave_idx_type GM_idx = 0; for (octave_idx_type frame = 0; frame < nFrames; frame++) { Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, @@ -1133,6 +1139,7 @@ Magick::DirectClass); Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + octave_idx_type GM_idx = 0; for (octave_idx_type col = 0; col < nCols; col++) { for (octave_idx_type row = 0; row < nRows; row++) @@ -1149,6 +1156,7 @@ // Save changes to underlying image. m_img.syncPixels (); imvec.push_back (m_img); + img_fvec += B_offset; } break; } @@ -1158,7 +1166,6 @@ // The fortran_vec offset for the green and blue channels const octave_idx_type G_offset = nCols * nRows; const octave_idx_type B_offset = nCols * nRows * 2; - octave_idx_type GM_idx = 0; for (octave_idx_type frame = 0; frame < nFrames; frame++) { Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, @@ -1166,6 +1173,7 @@ Magick::DirectClass); Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + octave_idx_type GM_idx = 0; for (octave_idx_type col = 0; col < nCols; col++) { for (octave_idx_type row = 0; row < nRows; row++) @@ -1184,6 +1192,7 @@ // Save changes to underlying image. m_img.syncPixels (); imvec.push_back (m_img); + img_fvec += B_offset; } break; } @@ -1194,7 +1203,6 @@ const octave_idx_type M_offset = nCols * nRows; const octave_idx_type Y_offset = nCols * nRows * 2; const octave_idx_type K_offset = nCols * nRows * 3; - octave_idx_type GM_idx = 0; for (octave_idx_type frame = 0; frame < nFrames; frame++) { Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, @@ -1202,6 +1210,7 @@ Magick::DirectClass); Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + octave_idx_type GM_idx = 0; for (octave_idx_type col = 0; col < nCols; col++) { for (octave_idx_type row = 0; row < nRows; row++) @@ -1219,6 +1228,7 @@ // Save changes to underlying image. m_img.syncPixels (); imvec.push_back (m_img); + img_fvec += K_offset; } break; } @@ -1229,7 +1239,6 @@ const octave_idx_type M_offset = nCols * nRows; const octave_idx_type Y_offset = nCols * nRows * 2; const octave_idx_type K_offset = nCols * nRows * 3; - octave_idx_type GM_idx = 0; for (octave_idx_type frame = 0; frame < nFrames; frame++) { Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, @@ -1238,6 +1247,7 @@ Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); Magick::IndexPacket *ind = m_img.getIndexes (); + octave_idx_type GM_idx = 0; for (octave_idx_type col = 0; col < nCols; col++) { for (octave_idx_type row = 0; row < nRows; row++) @@ -1257,6 +1267,7 @@ // Save changes to underlying image. m_img.syncPixels (); imvec.push_back (m_img); + img_fvec += K_offset; } break; }