/* gd_imgload.cc * * This octave function loads an image using the GD image library * (http://www.boutell.com/gd/). It is able to load the types of * images that GD can load (JPEG, PNG, and XBM -- though I have not * successfully used XBM yet). It takes one argument (the image file * to load) and returns 3 arguments that differ semantically depending * on whether the image was true-color or colormapped. If the image * was true color, then the three arguments returned are the 3 color * channels (red, green, blue). If the image was colormapped, then the * the three arguments are "colormapped" (a string), the pixels * (indexes into the colormap), and the colormap. This is kind of a * clunky way of returning values, but it is an okay first step. * * This function loads the image, and places the relevant data (rgb * data or pixels and colormap) into native Octave matrices, which are * then returned to the caller. * * This file can be compiled to a .oct file using the command: * "mkoctfile -lgd gd_imgload.cc" * Clearly, the GD and Octave development files must be installed to * compile this function. * * * Copyright (C) 2003 Greg Hamerly (greg_hamerly at baylor dot edu) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see http://www.gnu.org/copyleft/gpl.html */ /* standard io headers */ #include #include /* gd image library headers */ #include /* octave headers */ #include #include #include #include #include #include #include DEFUN_DLD (gd_imgload, args, , "[a, b, c] = gd_imgload (filename)\n\ \n\ Load an image into octave using the GD library image loading functions.\n\ Can load JPEG, PNG, and XBM files.\n\ Return values depend on whether the image was true-color or has a colormap.\n\ If the image has true-color, then\n\ a = red channel\n\ b = green channel\n\ c = blue channel\n\ This image can be displayed with imshow(a,b,c).\n\ If the image is colormapped, then\n\ a = 'colormapped' (a string)\n\ b = pixels\n\ c = the color map\n\ This image can be displayed with imshow(b,c).") { // The list of values to return. octave_value_list retval; // check the arguments to this function if (args.length() == 0) { octave_stdout << "Error: need to specify an image name\n"; return retval; } else if (! args(0).is_string()) { octave_stdout << "Error: need to specify an image name\n"; return retval; } std::string name = args(0).string_value(); octave_stdout << "loading file '" << name << "'\n"; /* open the image */ FILE *image_in = fopen(name.c_str(), "rb"); if (image_in == NULL) { octave_stdout << "Error: unable to access file '" << name << "'\n"; return retval; } /* load the image */ gdImagePtr im; int namelen = name.length(); if ((name.rfind(".jpg") == (namelen - strlen(".jpg"))) || (name.rfind(".jpeg") == (namelen - strlen(".jpeg")))) { im = gdImageCreateFromJpeg(image_in); } else if (name.rfind(".png") == (namelen - strlen(".png"))) { im = gdImageCreateFromPng(image_in); } else if (name.rfind(".xbm") == (namelen - strlen(".xbm"))) { im = gdImageCreateFromXbm(image_in); } else { octave_stdout << "Error: unknown file type (only know jpeg, png, xbm)\n"; return retval; } fclose(image_in); octave_stdout << "rows: " << im->sy << ", cols: " << im->sx << "\n"; octave_stdout << (im->trueColor ? "true color\n" : "color-mapped\n"); /* now we need to feed the values into an octave-style matrix * octave can do images in two ways: colormap (requires 2 matrices -- index * and map), and true color (requires 3 matrices -- r,g,b) */ if (im->trueColor) { // this is a true-color image -- create the rgb channels Matrix red(im->sy, im->sx), green(im->sy, im->sx), blue(im->sy, im->sx); for (int y = 0; y < im->sy; y++) { for (int x = 0; x < im->sx; x++) { red(y, x) = ((im->tpixels[y][x] >> 16) & 0xff) / 255.0; green(y, x) = ((im->tpixels[y][x] >> 8) & 0xff) / 255.0; blue(y, x) = (im->tpixels[y][x] & 0xff) / 255.0; } } retval(0) = octave_value(red); retval(1) = octave_value(green); retval(2) = octave_value(blue); } else { // this is a colormapped image Matrix pixels(im->sy, im->sx); Matrix colorMap(im->colorsTotal, 3); for (int y = 0; y < im->sy; y++) { for (int x = 0; x < im->sx; x++) { pixels(y, x) = im->pixels[y][x] + 1; } } for (int c = 0; c < im->colorsTotal; c++) { colorMap(c, 0) = im->red[c] / 255.0; colorMap(c, 1) = im->green[c] / 255.0; colorMap(c, 2) = im->blue[c] / 255.0; } retval(0) = octave_value("colormapped"); retval(1) = octave_value(pixels); retval(2) = octave_value(colorMap); } /* destroy the image in memory */ gdImageDestroy(im); return retval; }