00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00177 glMatrixMode(GL_PROJECTION);
00178 glLoadIdentity();
00179 glOrtho(0, reddata->GetWidth(), reddata->GetHeight(), 0, -1, 1);
00180 glMatrixMode(GL_MODELVIEW);
00181
00182 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00183 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00184
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
00193
00194
00195
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 }