Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 75fb554

Browse files
committed
added imread
svn path=/trunk/matplotlib/; revision=456
1 parent c1ed82d commit 75fb554

3 files changed

Lines changed: 66 additions & 34 deletions

File tree

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
New entries should be added at the top
22

3+
2004-07-28 Added image.imread with support for loading png into
4+
numerix arrays
5+
36
2004-07-28 Added key modifiers to events - implemented dynamic updates
47
and rubber banding for interactive pan/zoom - JDH
58

src/_image.cpp

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <iostream>
1+
#include <iostream>
22
#include <fstream>
33
#include <cmath>
44
#include <cstdio>
@@ -613,12 +613,12 @@ _image_module::from_images(const Py::Tuple& args) {
613613

614614

615615

616-
char _image_module_frompng__doc__[] =
617-
"frompng(fname)\n"
616+
char _image_module_readpng__doc__[] =
617+
"readpng(fname)\n"
618618
"\n"
619-
"Load the image from png file fname";
619+
"Load an image from png file into a numerix array of MxNx4 uint8";
620620
Py::Object
621-
_image_module::frompng(const Py::Tuple& args) {
621+
_image_module::readpng(const Py::Tuple& args) {
622622

623623
args.verify_length(1);
624624
std::string fname = Py::String(args[0]);
@@ -627,25 +627,25 @@ _image_module::frompng(const Py::Tuple& args) {
627627

628628
FILE *fp = fopen(fname.c_str(), "rb");
629629
if (!fp)
630-
throw Py::RuntimeError("_image_module::frompng could not open PNG file for reading");
630+
throw Py::RuntimeError("_image_module::readpng could not open PNG file for reading");
631631

632632
fread(header, 1, 8, fp);
633633
if (png_sig_cmp(header, 0, 8))
634-
throw Py::RuntimeError("_image_module::frompng: file not recognized as a PNG file");
634+
throw Py::RuntimeError("_image_module::readpng: file not recognized as a PNG file");
635635

636636

637637
/* initialize stuff */
638638
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
639639

640640
if (!png_ptr)
641-
throw Py::RuntimeError("_image_module::frompng: png_create_read_struct failed");
641+
throw Py::RuntimeError("_image_module::readpng: png_create_read_struct failed");
642642

643643
png_infop info_ptr = png_create_info_struct(png_ptr);
644644
if (!info_ptr)
645-
throw Py::RuntimeError("_image_module::frompng: png_create_info_struct failed");
645+
throw Py::RuntimeError("_image_module::readpng: png_create_info_struct failed");
646646

647647
if (setjmp(png_jmpbuf(png_ptr)))
648-
throw Py::RuntimeError("_image_module::frompng: error during init_io");
648+
throw Py::RuntimeError("_image_module::readpng: error during init_io");
649649

650650
png_init_io(png_ptr, fp);
651651
png_set_sig_bytes(png_ptr, 8);
@@ -654,41 +654,70 @@ _image_module::frompng(const Py::Tuple& args) {
654654

655655
png_uint_32 width = info_ptr->width;
656656
png_uint_32 height = info_ptr->height;
657-
//int color_type = info_ptr->color_type;
658-
//int bit_depth = info_ptr->bit_depth;
659-
//int number_of_passes = png_set_interlace_handling(png_ptr);
657+
658+
// convert misc color types to rgb for simplicity
659+
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
660+
info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
661+
png_set_gray_to_rgb(png_ptr);
662+
else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
663+
png_set_palette_to_rgb(png_ptr);
664+
665+
666+
int bit_depth = info_ptr->bit_depth;
667+
if (bit_depth == 16) png_set_strip_16(png_ptr);
668+
669+
670+
png_set_interlace_handling(png_ptr);
660671
png_read_update_info(png_ptr, info_ptr);
661672

673+
bool rgba = info_ptr->color_type == PNG_COLOR_TYPE_RGBA;
674+
if ( (info_ptr->color_type != PNG_COLOR_TYPE_RGB) || rgba) {
675+
std::cerr << "Found color type " << (int)info_ptr->color_type << std::endl;
676+
throw Py::RuntimeError("_image_module::readpng: cannot handle color_type");
677+
}
662678

663679
/* read file */
664680
if (setjmp(png_jmpbuf(png_ptr)))
665-
throw Py::RuntimeError("_image_module::frompng: error during read_image");
681+
throw Py::RuntimeError("_image_module::readpng: error during read_image");
666682

667-
png_bytep* row_pointers = new png_bytep[height];
668-
if (row_pointers ==NULL) //todo: also handle allocation throw
669-
throw Py::MemoryError("_image_module::frompng: could not allocate memory");
683+
png_bytep row_pointers[height];
670684

671-
for (png_uint_32 y=0; y<height; y++)
672-
row_pointers[y] = new png_byte[info_ptr->rowbytes]; // todo: delete?
685+
for (png_uint_32 row = 0; row < height; row++)
686+
row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr,info_ptr)];
673687

674688
png_read_image(png_ptr, row_pointers);
675689

676690

677-
Image* imo = new Image;
678-
imo->rowsIn = height;
679-
imo->colsIn = width;
680-
681-
size_t NUMBYTES(imo->colsIn * imo->rowsIn * imo->BPP);
691+
692+
int dimensions[3];
693+
dimensions[0] = height; //numrows
694+
dimensions[1] = width; //numcols
695+
dimensions[2] = 4;
682696

683-
imo->bufferIn = new agg::int8u[NUMBYTES]; //todo: copy row_pointers in
697+
PyArrayObject *A = (PyArrayObject *) PyArray_FromDims(3, dimensions, PyArray_FLOAT);
684698

685-
for (png_uint_32 row = 0; row < imo->rowsIn; ++row) {
686-
imo->bufferIn = row_pointers[row];
699+
700+
for (png_uint_32 y = 0; y < height; y++) {
701+
png_byte* row = row_pointers[y];
702+
for (png_uint_32 x = 0; x < width; x++) {
703+
704+
png_byte* ptr = (rgba) ? &(row[x*4]) : &(row[x*3]);
705+
size_t offset = y*A->strides[0] + x*A->strides[1];
706+
//if ((y<10)&&(x==10)) std::cout << "r = " << ptr[0] << " " << ptr[0]/255.0 << std::endl;
707+
*(float*)(A->data + offset + 0*A->strides[2]) = ptr[0]/255.0;
708+
*(float*)(A->data + offset + 1*A->strides[2]) = ptr[1]/255.0;
709+
*(float*)(A->data + offset + 2*A->strides[2]) = ptr[2]/255.0;
710+
*(float*)(A->data + offset + 3*A->strides[2]) = rgba ? ptr[3]/255.0 : 1.0;
711+
}
687712
}
688-
689-
imo->rbufIn = new agg::rendering_buffer;
690-
imo->rbufIn->attach(imo->bufferIn, imo->colsIn, imo->rowsIn, imo->colsIn*imo->BPP);
691-
return Py::asObject( imo );
713+
714+
//free the png memory
715+
png_read_end(png_ptr, info_ptr);
716+
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
717+
fclose(fp);
718+
for (png_uint_32 row = 0; row < height; row++)
719+
delete [] row_pointers[row];
720+
return Py::asObject((PyObject*)A);
692721
}
693722

694723

src/_image.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ class _image_module : public Py::ExtensionModule<_image_module>
9191

9292
add_varargs_method("fromarray", &_image_module::fromarray,
9393
"fromarray");
94-
add_varargs_method("frompng", &_image_module::frompng,
95-
"frompng");
94+
add_varargs_method("readpng", &_image_module::readpng,
95+
"readpng");
9696
add_varargs_method("from_images", &_image_module::from_images,
9797
"from_images");
9898
initialize( "The _image module" );
@@ -103,7 +103,7 @@ class _image_module : public Py::ExtensionModule<_image_module>
103103
private:
104104

105105
Py::Object fromarray (const Py::Tuple &args);
106-
Py::Object frompng (const Py::Tuple &args);
106+
Py::Object readpng (const Py::Tuple &args);
107107
Py::Object from_images (const Py::Tuple &args);
108108
static char _image_module_fromarray__doc__[];
109109

0 commit comments

Comments
 (0)