Hauptseite   Klassenhierarchie   Auflistung der Dateien  

rgbimage.cpp

00001 /**********************************************************************************
00002 * Copyright (c) 2003, Christoph Rueegg <opendev@cdrnet.ch> and Matthias Bader     *
00003 * Partially based on ideas of Tim Weyrich <weyrich@inf.ethz.ch>                   *
00004 * and/or the Swiss Federal Institute of Technology http://www.ethz.ch             *
00005 * All rights reserved.                                                            *
00006 *                                                                                 *
00007 * Project Website: http://www.cdrnet.net/projects/painter/                        *
00008 *                                                                                 *
00009 * Redistribution and use in source and binary forms, with or without modification,*
00010 * are permitted provided that the following conditions are met:                   *
00011 *                                                                                 *
00012 * 1. Redistributions of source code must retain the above copyright notice,       *
00013 * this list of conditions and the following disclaimer.                           *
00014 *                                                                                 *
00015 * 2. Redistributions in binary form must reproduce the above copyright notice,    *
00016 * this list of conditions and the following disclaimer in the documentation       *
00017 * and/or other materials provided with the distribution.                          *
00018 *                                                                                 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"     *
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       *
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE      *
00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE        *
00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR             *
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF            *
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS        *
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN         *
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)         *
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF          *
00029 * THE POSSIBILITY OF SUCH DAMAGE.                                                 *
00030 **********************************************************************************/
00031 
00032 #include "rgbimage.h"
00033 #include "alphaimage.h"
00034 #include "hybridchannel.cpp"
00035 
00036 RgbImage::RgbImage(HybridRgbaChannel<unsigned char>* red, HybridRgbaChannel<unsigned char>* green, HybridRgbaChannel<unsigned char>* blue): AlphaImage(red->GetHeight(),red->GetWidth())
00037 {
00038   reddata = red;
00039   greendata = green;
00040   bluedata = blue;
00041   redfilter = reddata;
00042   greenfilter = greendata;
00043   bluefilter = bluedata;
00044   reddata->SetId(1);
00045   greendata->SetId(2);
00046   bluedata->SetId(3);
00047 }
00048 
00049 RgbImage::RgbImage(const int height, const int width): AlphaImage(height,width)
00050 {
00051   reddata = new HybridRgbaChannel<unsigned char>(height,width);
00052   greendata = new HybridRgbaChannel<unsigned char>(height,width);
00053   bluedata = new HybridRgbaChannel<unsigned char>(height,width);
00054   redfilter = reddata;
00055   greenfilter = greendata;
00056   bluefilter = bluedata;
00057   reddata->SetId(1);
00058   greendata->SetId(2);
00059   bluedata->SetId(3);
00060 }
00061 
00062 RgbImage::~RgbImage()
00063 {
00064   delete bluedata;
00065   delete greendata;
00066   delete reddata;
00067 }        
00068 
00069 inline unsigned char RgbImage::GetLuminance(const int x, const int y)
00070 {
00071   return(char(float(reddata->Get(x,y)+greendata->Get(x,y)+bluedata->Get(x,y))/3.0f));
00072 }
00073 
00074 inline void RgbImage::SetLuminance(const int x, const int y, const unsigned char val)
00075 {
00076   redfilter->Set(x,y,val);
00077   greenfilter->Set(x,y,val);
00078   bluefilter->Set(x,y,val);
00079 }
00080 
00081 inline unsigned char RgbImage::GetRed(const int x, const int y)
00082 {
00083   return(redfilter->Get(x,y));
00084 }
00085 
00086 inline void RgbImage::SetRed(const int x, const int y, const unsigned char val)
00087 {
00088   redfilter->Set(x,y,val);
00089 }
00090 
00091 inline unsigned char RgbImage::GetGreen(const int x, const int y)
00092 {
00093   return(greenfilter->Get(x,y));
00094 }
00095 
00096 inline void RgbImage::SetGreen(const int x, const int y, const unsigned char val)
00097 {
00098   greenfilter->Set(x,y,val);
00099 }
00100 
00101 inline unsigned char RgbImage::GetBlue(const int x, const int y)
00102 {
00103   return(bluefilter->Get(x,y));
00104 }
00105 
00106 inline void RgbImage::SetBlue(const int x, const int y, const unsigned char val)
00107 {
00108   bluefilter->Set(x,y,val);
00109 }
00110 
00111 void RgbImage::AttachLuminanceFilter(ChannelFilter<unsigned char>* filter)
00112 {
00113   ChannelFilter<unsigned char>* filter2 = filter->EmptyClone();
00114   ChannelFilter<unsigned char>* filter3 = filter->EmptyClone();  
00115   AttachRedFilter(filter);
00116   AttachGreenFilter(filter2);
00117   AttachBlueFilter(filter3);
00118 }
00119 
00120 void RgbImage::RemoveLuminanceFilters()
00121 {
00122   RemoveRedFilters();
00123   RemoveGreenFilters();
00124   RemoveBlueFilters();
00125 }
00126 
00127 void RgbImage::AttachRedFilter(ChannelFilter<unsigned char>* filter)
00128 {
00129   filter->SetSubChannel(redfilter);
00130   redfilter = filter;
00131   filter->SetId(1);
00132 }
00133 
00134 void RgbImage::RemoveRedFilters()
00135 {
00136   redfilter->ResetChannel();
00137   redfilter = reddata;
00138 }
00139 
00140 void RgbImage::AttachGreenFilter(ChannelFilter<unsigned char>* filter)
00141 {
00142   filter->SetSubChannel(greenfilter);
00143   greenfilter = filter;
00144   filter->SetId(2);
00145 }
00146 
00147 void RgbImage::RemoveGreenFilters()
00148 {
00149   greenfilter->ResetChannel();
00150   greenfilter = greendata;
00151 }
00152 
00153 void RgbImage::AttachBlueFilter(ChannelFilter<unsigned char>* filter)
00154 {
00155   filter->SetSubChannel(bluefilter);
00156   bluefilter = filter;
00157   filter->SetId(3);
00158 }
00159 
00160 void RgbImage::RemoveBlueFilters()
00161 {
00162   bluefilter->ResetChannel();
00163   bluefilter = bluedata;
00164 }
00165 
00166 double RgbImage::Draw()
00167 {
00168   GLdouble xFract, yFract, zoom;
00169   GLint vp[4];
00170   glGetIntegerv(GL_VIEWPORT, vp);
00171   xFract = (GLdouble)vp[2] / reddata->GetWidth();
00172   yFract = (GLdouble)vp[3] / reddata->GetHeight();
00173   zoom = (xFract < yFract) ? xFract : yFract;
00174   if(zoom > 1.0)
00175     zoom = (int)zoom;
00176   /* set up OpenGL projection matrix */
00177   glMatrixMode(GL_PROJECTION);
00178   glLoadIdentity();
00179   glOrtho(0, reddata->GetWidth(), reddata->GetHeight(), 0, -1, 1);
00180   glMatrixMode(GL_MODELVIEW);
00181   /* set up memory alignment */
00182   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00183   glPixelStorei(GL_PACK_ALIGNMENT, 1);
00184   /* clear buffer and draw image */
00185   glClearColor(0.3,0.4,0.4,1.0);
00186   glClear(GL_COLOR_BUFFER_BIT);
00187   glRasterPos2d(0, 0);
00188   glPixelZoom(zoom, -zoom);
00189   glDrawPixels(reddata->GetWidth(), reddata->GetHeight(),GL_RGBA,GL_UNSIGNED_BYTE,*(reddata->GetRawRgbData()));
00190   glutSwapBuffers();
00191   return((double)zoom);
00192   //no output; clear buffers ...
00193   //glClear(GL_COLOR_BUFFER_BIT);
00194   //glutSwapBuffers();
00195   //return(1.0);
00196 }
00197 
00198 RgbImage* RgbImage::CreateFromTiff(const char* filename)
00199 {
00200   TIFF *tif;
00201   if ((tif = TIFFOpen(filename, "r")) != NULL)
00202   {
00203     uint32 width, height;
00204     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
00205     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
00206     HybridRgbaChannel<unsigned char>* red = new HybridRgbaChannel<unsigned char>(height,width);
00207     HybridRgbaChannel<unsigned char>* green = (HybridRgbaChannel<unsigned char>*) red->EmptyClone();
00208     HybridRgbaChannel<unsigned char>* blue = (HybridRgbaChannel<unsigned char>*) red->EmptyClone();
00209     red->SetId(1);
00210     green->SetId(2);
00211     blue->SetId(3);
00212     RgbImage* result = new RgbImage(red,green,blue);
00213     uint32 *buf = new uint32[width*height];
00214     if (TIFFReadRGBAImage(tif, width, height, buf, 0))
00215     {
00216       uint32  *p;
00217       int q,c;
00218       for (p=buf+width*(height-1),q=0;p >= buf;p-=width, q++)
00219         for (c=width-1; c>=0; c--)
00220         {
00221           red->Set(c,q,(unsigned char)TIFFGetR(p[c]));
00222           green->Set(c,q,(unsigned char)TIFFGetG(p[c]));
00223           blue->Set(c,q,(unsigned char)TIFFGetB(p[c]));
00224         }  
00225     }
00226     else
00227     {
00228       delete result;
00229       result = 0;
00230     }
00231     delete [] buf;
00232     TIFFClose(tif);
00233     return result;
00234   }
00235   return 0;
00236 }
00237 
00238 void RgbImage::WriteToTiff(const char* filename)
00239 {
00240   TIFF  *tif;
00241   if ((tif = TIFFOpen(filename, "w")) != NULL)
00242   {
00243     int  y;
00244 
00245     TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
00246     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, GetWidth());
00247     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, GetHeight());
00248     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
00249     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8, 8, 8, 8);
00250     TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
00251     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
00252     TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, filename);
00253     TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Created With My Personal Painter Application :-)");
00254     TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
00255     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 64);
00256     TIFFSetField(tif, TIFFTAG_XRESOLUTION, 75.0);
00257     TIFFSetField(tif, TIFFTAG_YRESOLUTION, 75.0);
00258     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00259     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
00260     RgbaPixel<unsigned char> *data = *(reddata->GetRawRgbData());
00261     for (y=0; y<GetHeight(); y++)
00262       if (TIFFWriteScanline(tif, data+y*GetWidth(), y, 0) < 0)
00263         break;
00264     if (y < GetHeight())
00265       cerr << "Error while writing to TIFF file." << endl;
00266     TIFFClose(tif);
00267   }
00268   else
00269     cerr << "Couldn't open `" << filename << "' for writing." << endl;
00270 }

Erzeugt am Fri Jan 31 15:27:35 2003 für OOP Miniprojekt von doxygen1.3-rc2