00001 /*!@file QtUtil/ImageConvert.C Functions to convert our images to QImage or QPixmap 00002 */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/QtUtil/ImageConvert.C $ 00035 // $Id: ImageConvert.C 12424 2009-12-29 02:28:32Z rand $ 00036 // 00037 00038 #ifndef IMAGE_CONVERT_QT_C_DEFINED 00039 #define IMAGE_CONVERT_QT_C_DEFINED 00040 00041 #ifdef INVT_HAVE_QT3 00042 00043 #include "QtUtil/ImageConvert.H" 00044 00045 #include "Image/Image.H" 00046 #include "Image/Pixels.H" 00047 00048 #include <qimage.h> 00049 #include <vector> 00050 00051 namespace 00052 { 00053 bool isLittleEndian() 00054 { 00055 union 00056 { 00057 int i; 00058 byte b[sizeof(int)]; 00059 } u; 00060 memset(&u, 0, sizeof(u)); 00061 u.b[0] = 1; 00062 if (u.i == 1) 00063 return true; 00064 00065 // else ... 00066 return false; 00067 } 00068 } 00069 00070 // ###################################################################### 00071 QPixmap convertToQPixmap(const Image<PixRGB<byte> >& img) 00072 { 00073 // allocate 32-bit buffer 00074 std::vector<uchar> buf(img.getSize()*4); 00075 uchar* dataptr = &buf[0]; 00076 00077 // copy data to buffer, max alpha 00078 Image<PixRGB<byte> >::const_iterator sptr = img.begin(); 00079 Image<PixRGB<byte> >::const_iterator stop = img.end(); 00080 00081 if (isLittleEndian()) 00082 while (sptr != stop) 00083 { 00084 *dataptr++ = (*sptr).p[2]; 00085 *dataptr++ = (*sptr).p[1]; 00086 *dataptr++ = (*sptr).p[0]; 00087 *dataptr++ = 255; 00088 ++sptr; 00089 } 00090 else 00091 while (sptr != stop) 00092 { 00093 *dataptr++ = 255; 00094 *dataptr++ = (*sptr).p[0]; 00095 *dataptr++ = (*sptr).p[1]; 00096 *dataptr++ = (*sptr).p[2]; 00097 ++sptr; 00098 } 00099 00100 // create and return QImage 00101 QImage qimg(&buf[0], img.getWidth(), img.getHeight(), 32, 0, 0, 00102 QImage::IgnoreEndian); 00103 00104 // NOTE! We can't just return the QImage directly here, like we used 00105 // to do -- http://doc.trolltech.com/3.3/qimage.html#QImage-7 states 00106 // that "The buffer must remain valid throughout the life of the 00107 // QImage". Therefore, if we return the QImage directly, its memory 00108 // becomes invalid because our temporary 'data' array goes out of 00109 // scope. This won't necessarily cause a crash, but it will mean 00110 // that some of our image data will get trashed as the stack 00111 // contents are overwritten by subsequent calls. So, instead we 00112 // return a QPixmap which contains its own private copy of the data. 00113 00114 return QPixmap(qimg); 00115 } 00116 00117 // ###################################################################### 00118 QPixmap convertToQPixmap(const Image<byte>& img) 00119 { 00120 // allocate 32-bit buffer (can it be done with less bits per pixel??) 00121 std::vector<uchar> buf(img.getSize()*4); 00122 uchar* pdata = &buf[0]; 00123 00124 // copy data to buffer, max alpha 00125 Image<byte>::const_iterator sptr = img.begin(); 00126 Image<byte>::const_iterator stop = img.end(); 00127 00128 if (isLittleEndian()) 00129 while (sptr != stop) 00130 { 00131 *pdata++ = *sptr; 00132 *pdata++ = *sptr; 00133 *pdata++ = *sptr; 00134 *pdata++ = 255; 00135 ++sptr; 00136 } 00137 else 00138 while (sptr != stop) 00139 { 00140 *pdata++ = 255; 00141 *pdata++ = *sptr; 00142 *pdata++ = *sptr; 00143 *pdata++ = *sptr; 00144 ++sptr; 00145 } 00146 00147 // create and return QImage 00148 QImage qimg(&buf[0], img.getWidth(), img.getHeight(), 32, 0, 0, 00149 QImage::IgnoreEndian); 00150 00151 // NOTE! We can't just return the QImage directly here, like we used 00152 // to do -- http://doc.trolltech.com/3.3/qimage.html#QImage-7 states 00153 // that "The buffer must remain valid throughout the life of the 00154 // QImage". Therefore, if we return the QImage directly, its memory 00155 // becomes invalid because our temporary 'data' array goes out of 00156 // scope. This won't necessarily cause a crash, but it will mean 00157 // that some of our image data will get trashed as the stack 00158 // contents are overwritten by subsequent calls. So, instead we 00159 // return a QPixmap which contains its own private copy of the data. 00160 00161 return QPixmap(qimg); 00162 } 00163 00164 // ###################################################################### 00165 Image<PixRGB<byte> > convertToImage(const QPixmap& qpixm) 00166 { 00167 QImage qimg; 00168 qimg = qpixm; 00169 00170 Image<PixRGB<byte> > result(qimg.width(), qimg.height(), NO_INIT); 00171 00172 Image<PixRGB<byte> >::iterator dptr = result.beginw(); 00173 Image<PixRGB<byte> >::iterator stop = result.endw(); 00174 00175 for (int y = 0; y < qimg.height(); ++y) 00176 for (int x = 0; x < qimg.width(); ++x) 00177 { 00178 QRgb pix = qimg.pixel(x, y); 00179 *dptr++ = PixRGB<byte>((pix & 0x00ff0000) >> 16, 00180 (pix & 0x0000ff00) >> 8, 00181 (pix & 0x000000ff)); 00182 } 00183 00184 ASSERT(dptr == stop); 00185 00186 return result; 00187 } 00188 #endif //IMAGE_CONVERT_QT_C_DEFINED 00189 #endif //INVT_HAVE_QT3 00190 00191 // ###################################################################### 00192 /* So things look consistent in everyone's emacs... */ 00193 /* Local Variables: */ 00194 /* indent-tabs-mode: nil */ 00195 /* End: */