From octave-sources-request at bevo dot che dot wisc dot edu Fri Jan 5 19:25:04 2001 Subject: Colour management using ICC profiles From: adler at freenet dot carleton dot ca To: octave-sources at bevo dot che dot wisc dot edu Date: Fri, 5 Jan 2001 20:31:34 -0500 (EST) The following code implements image colour management using ICC profiles for octave. It depends on the lcms library; the build instructions are in the header. For more information of ICC colour management, take a look at the references in the header. _______________________________________ Andy Adler, adler at ncf dot ca /* * Octave dl code to do image conversions using icc colour profiles. * * (c) 2001 Andy Adler * $Id: icc_cnvt.cc,v 1.1 2001/01/05 17:45:22 aadler Exp aadler $ * * Note, this file depends on the littlecms library, * available at www.littlecms.com. * * Build Instructions: * * 1. Download the unix version of lcms from * http://www.littlecms.com/download.htm * * 2. Build the lcms using * ./configure * make * * 3. Set: LCMS=/source * * 4. Make this file: * mkoctfile icc_cnvt.cc -I$LCMS -L$LCMS -llcms * * Note: * * For more information about icc colour management, refer to * www.color.org * www.coloraid.de * www.freecolormanagement.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include "lcms.h" DEFUN_DLD (icc_cnvt, args, , "img_out = icc_cnvt (img_in, prof1, prof2, intent)\n\ \n\ img_out - output image with red, green, blue components\n\ ( img_out.r, img_out.g, img_out.b )\n\ img_in - input image with red, green, blue components\n\ ( img_in.r, img_in.g, img_in.b )\n\ \n\ Note: images components must be (0-255)\n\ \n\ prof1 - input icc colour profile filename (AtoB)\n\ prof2 - input output colour profile filename (BtoA)\n\ intent - rendering intent: one of\n\ INTENT_PERCEPTUAL - default\n\ INTENT_RELATIVE_COLORIMETRIC\n\ INTENT_SATURATION\n\ INTENT_ABSOLUTE_COLORIMETRIC\n\ ") { // The list of values to return. See the declaration in oct-obj.h octave_value_list retval; int nargin= args.length(); if ( nargin < 3 || !args(0).is_map() || !args(1).is_string() || !args(2).is_string() ) { usage( "icc_cnvt" ); return retval; } int Intent= INTENT_PERCEPTUAL; if (nargin >=4) { string intent= args(3).string_value(); if (intent=="INTENT_PERCEPTUAL") Intent= INTENT_PERCEPTUAL; else if (intent=="INTENT_RELATIVE_COLORIMETRIC") Intent= INTENT_RELATIVE_COLORIMETRIC; else if (intent=="INTENT_SATURATION") Intent= INTENT_SATURATION; else if (intent=="INTENT_ABSOLUTE_COLORIMETRIC") Intent= INTENT_ABSOLUTE_COLORIMETRIC; printf("%s->%d\n", intent.c_str(), Intent); } Octave_map c_in= args(0).map_value(); const Matrix r0= c_in["r"].matrix_value(); const Matrix g0= c_in["g"].matrix_value(); const Matrix b0= c_in["b"].matrix_value(); int n= r0.rows(); int m= r0.cols(); if ( m != g0.cols() || m != b0.cols() || n != g0.rows() || n != g0.rows() ) { error("R,G,B, components must be same size"); return retval; } // Output Matrices Matrix r1( n,m ); Matrix g1( n,m ); Matrix b1( n,m ); // // Colour processing starts here // cmsHPROFILE hInProfile = cmsOpenProfileFromFile(args(1).string_value().c_str(), "r"); cmsHPROFILE hOutProfile = cmsOpenProfileFromFile(args(2).string_value().c_str(), "r"); cmsHTRANSFORM hTransform = cmsCreateTransform(hInProfile, TYPE_RGB_8, hOutProfile, TYPE_RGB_8, Intent, 0); unsigned char inbuf [3*m]; unsigned char outbuf[3*m]; for (int i=0; i < n; i++) { for( int j=0,p=0; j < m; j++ ) { inbuf[ p++ ] = (unsigned int) r0(i,j); inbuf[ p++ ] = (unsigned int) g0(i,j); inbuf[ p++ ] = (unsigned int) b0(i,j); } cmsDoTransform(hTransform, inbuf, outbuf, m ); for( int j=0,p=0; j < m; j++ ) { r1(i,j) = outbuf[ p++ ]; g1(i,j) = outbuf[ p++ ]; b1(i,j) = outbuf[ p++ ]; } } cmsDeleteTransform(hTransform); cmsCloseProfile(hInProfile); cmsCloseProfile(hOutProfile); Octave_map c_out; c_out["r"]= r1; c_out["g"]= g1; c_out["b"]= b1; retval(0)= c_out; return retval; } ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------