00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <new>
00023 #include <string.h>
00024 #include <MicrosoftBMP_RT.h>
00025 #include <MicrosoftRCBMP_RT.h>
00026 #include <MicrosoftMonoBMP_RT.h>
00027
00028 #include "ImageRGB.h"
00029
00030
00031 ImageRGB::ImageRGB(ImageRGB& img) : ImageBase(img)
00037 {
00038 unsigned int array_size = img.width * img.height;
00039 data = new PixelRGB[array_size];
00040
00041 *this = img;
00042 }
00043
00044 ImageRGB::ImageRGB(ImageRGB& img,
00045 unsigned int min_x,
00046 unsigned int min_y,
00047 unsigned int max_x,
00048 unsigned int max_y) : ImageBase(max_x-min_x+1, max_y-min_y+1)
00057 {
00058 data = new PixelRGB[width*height];
00059 copy(img, min_x, min_y, max_x, max_y, 0, 0) ;
00060 }
00061
00062 ImageRGB::ImageRGB(unsigned int w, unsigned int h) : ImageBase(w,h)
00071 {
00072 unsigned int array_size = width * height;
00073 data = new PixelRGB[array_size];
00074
00075
00076 }
00077
00078 ImageRGB::ImageRGB(char *filename, FileFormat format)
00087 {
00088
00089 if(format == FORMAT_BMP_24){
00090 MicrosoftBMP_RT bmp(filename) ;
00091
00092 if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00093
00094 width = bmp.ImageWidth ;
00095 height = bmp.ImageHeight ;
00096
00097 data = new PixelRGB[width*height] ;
00098
00099 bmp.extract_data((int *)data) ;
00100 }
00101 else if(format == FORMAT_BMP_RC){
00102 MicrosoftRCBMP_RT bmp(filename) ;
00103
00104 if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00105
00106 width = bmp.ImageWidth ;
00107 height = bmp.ImageHeight ;
00108
00109 data = new PixelRGB[width*height] ;
00110
00111 bmp.extract_data((int *)data) ;
00112 }
00113 else if(format == FORMAT_BMP_MONO){
00114 MicrosoftMonoBMP_RT bmp(filename) ;
00115
00116 if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00117
00118 width = bmp.ImageWidth ;
00119 height = bmp.ImageHeight ;
00120
00121 data = new PixelRGB[width*height] ;
00122
00123 bmp.extract_data((int *)data) ;
00124 }
00125 else if(format == FORMAT_BMP_ANY){
00126
00127 MicrosoftBMP_RT* bmp ;
00128 MicrosoftRCBMP_RT *bmp_rc;
00129 MicrosoftMonoBMP_RT *bmp_mono;
00130
00131 if((bmp = new MicrosoftBMP_RT(filename)) != NULL &&
00132 bmp->read()){
00133
00134 width = bmp->ImageWidth ;
00135 height = bmp->ImageHeight ;
00136
00137 data = new PixelRGB[width*height] ;
00138
00139 bmp->extract_data((int *)data) ;
00140 }
00141 else if((bmp_rc = new MicrosoftRCBMP_RT(filename)) != NULL &&
00142 bmp_rc->read()){
00143
00144 width = bmp_rc->ImageWidth ;
00145 height = bmp_rc->ImageHeight ;
00146
00147 data = new PixelRGB[width*height] ;
00148
00149 bmp_rc->extract_data((int *)data) ;
00150
00151 }
00152 else if((bmp_mono = new MicrosoftMonoBMP_RT(filename)) != NULL &&
00153 bmp_mono->read()){
00154
00155 width = bmp_mono->ImageWidth ;
00156 height = bmp_mono->ImageHeight ;
00157
00158 data = new PixelRGB[width*height] ;
00159
00160 bmp_mono->extract_data((int *)data) ;
00161 }
00162 }
00163
00164
00165 }
00166
00167 ImageRGB::~ImageRGB()
00171 {
00172 delete [] data;
00173 }
00174
00175
00176 void ImageRGB::set_pixel(unsigned int x, unsigned int y, PixelRGB p)
00183 {
00184
00185 if (x > width || y > height)
00186 throw "Invalid Coordinates in method set_rgb";
00187
00188 data[y * width + x] = p;
00189 }
00190
00191
00192 void ImageRGB::set_rgb(unsigned int x, unsigned int y,
00193 int red, int green, int blue)
00203 {
00204
00205 if (x > width || y > height)
00206 throw "Invalid Coordinates in method set_rgb";
00207
00208 unsigned int offset = y * width + x;
00209
00210 data[offset][RED] = red;
00211 data[offset][GREEN] = green;
00212 data[offset][BLUE] = blue;
00213 }
00214
00215
00216 void ImageRGB::set_field(unsigned int x, unsigned int y,
00217 FieldSelector fs, int value)
00226 {
00227
00228 if (x > width || y > height)
00229 throw "Invalid Coordinates in method set_field";
00230
00231 unsigned int offset = y * width + x;
00232 data[offset][fs] = value;
00233 }
00234
00235
00236 void ImageRGB::get_pixel(unsigned int x, unsigned int y, PixelRGB& p)
00245 {
00246 unsigned int offset = y * width + x;
00247
00248 p[ RED ] = data[offset][RED];
00249 p[GREEN] = data[offset][GREEN];
00250 p[ BLUE] = data[offset][BLUE];
00251 }
00252
00253
00254 int ImageRGB::get_field(unsigned int x, unsigned int y, FieldSelector fs)
00263 {
00264 unsigned int offset = y * width + x;
00265 return data[offset][fs];
00266 }
00267
00268
00269 ImageRGB& ImageRGB::clear(int k)
00275 {
00276 int *start = data[0];
00277 int *end = start + width * height * 3;
00278
00279 for (int *d = start; d < end; d++) *d = k;
00280
00281 return *this;
00282 }
00283
00284
00285 ImageRGB& ImageRGB::clear(PixelRGB& p)
00291 {
00292 int *start = data[0];
00293 int *end = start + width * height * 3;
00294
00295 for (int *d = start; d < end; d += 3) {
00296 d[ RED ] = p[ RED ];
00297 d[GREEN] = p[GREEN];
00298 d[ BLUE] = p[ BLUE];
00299 }
00300
00301 return *this;
00302 }
00303
00304
00305 ImageRGB& ImageRGB::clear_field(FieldSelector fs, int k)
00312 {
00313 int *start = data[0];
00314 int *end = start + width * height * 3;
00315
00316 for (int *d = start + fs; d < end; d += 3) *d = k;
00317
00318 return *this;
00319 }
00320
00321
00322 ImageRGB& ImageRGB::copy(ImageRGB& img)
00329 {
00330
00331 if (this == &img)
00332 throw "Source and Destination are same Image";
00333
00334
00335 if (width != img.width || height != img.height)
00336 throw "Difference in ImageRGB Dimensions";
00337
00338
00339 memcpy(data, img.data, width * height * 3 * sizeof(int));
00340
00341 return *this;
00342 }
00343
00344 ImageRGB& ImageRGB::copy(ImageRGB& img,
00345 unsigned int min_x,
00346 unsigned int min_y,
00347 unsigned int max_x,
00348 unsigned int max_y,
00349 unsigned int start_x,
00350 unsigned int start_y)
00363 {
00364 unsigned int sx ;
00365 unsigned int sy ;
00366 unsigned int cntx ;
00367 unsigned int cnty ;
00368 int *s_ptr ;
00369 int *d_ptr ;
00370 unsigned int s_width ;
00371
00372 s_width = img.get_width() ;
00373
00374
00375 if (this == &img)
00376 throw "Source and Destination are same Image";
00377
00378
00379 if(min_x > max_x || min_y > max_y)
00380 throw "Invalid arguments to ImageRGB::copy()" ;
00381
00382
00383 sx = max_x - min_x + 1 ;
00384 sy = max_y - min_y + 1 ;
00385
00386 if(sx+start_x > width ||
00387 sy+start_y > height)
00388 throw "Dest. image is not big enough" ;
00389
00390 if(max_x > s_width ||
00391 max_y > img.get_height() )
00392 throw "Source images is not big enough" ;
00393
00394 for(cnty=0 ; cnty<sy ; cnty++){
00395
00396 s_ptr = (int*)img.data + (min_x + (min_y+cnty)*s_width)*3 ;
00397 d_ptr = (int*)data + (start_x + (start_y+cnty)*width)*3 ;
00398
00399 for(cntx=0 ; cntx<sx ; cntx++){
00400
00401 *(d_ptr++) = *(s_ptr++) ;
00402 *(d_ptr++) = *(s_ptr++) ;
00403 *(d_ptr++) = *(s_ptr++) ;
00404 }
00405 }
00406
00407 return *this;
00408 }
00409
00410 bool ImageRGB::save(char *filename, FileFormat format)
00417 {
00418
00419 bool ret_val = true ;
00420
00421 if(format == FORMAT_BMP_24 || format==FORMAT_BMP_ANY){
00422
00423 MicrosoftBMP_RT *btmp;
00424 btmp = new MicrosoftBMP_RT(filename);
00425 if(btmp==NULL) ret_val = false ;
00426 else if(!btmp->set_size(width,height)) ret_val = false ;
00427 else{
00428 btmp->put_data((int *)data) ;
00429 ret_val = btmp->write();
00430 }
00431 delete btmp ;
00432 }
00433 else if(format == FORMAT_BMP_RC){
00434
00435 MicrosoftRCBMP_RT *btmp;
00436 btmp = new MicrosoftRCBMP_RT(filename);
00437 if(btmp==NULL) ret_val = false ;
00438 else if(!btmp->set_size(width,height)) ret_val = false ;
00439 else if(!btmp->set_palette_grey256()) ret_val = false ;
00440 else{
00441 btmp->put_data((int *)data) ;
00442 ret_val = btmp->write();
00443 }
00444 delete btmp ;
00445 }
00446 else if(format == FORMAT_BMP_MONO){
00447
00448 MicrosoftMonoBMP_RT *btmp;
00449 btmp = new MicrosoftMonoBMP_RT(filename);
00450 if(btmp==NULL) ret_val = false ;
00451 else if(!btmp->set_size(width,height)) ret_val = false ;
00452 else{
00453 btmp->put_data((int *)data) ;
00454 ret_val = btmp->write();
00455 }
00456 delete btmp ;
00457 }
00458
00459 return ret_val ;
00460 }
00461
00462 bool ImageRGB::enhance_contrast()
00467 {
00468 unsigned int cnt ;
00469 int max_val = 0 ;
00470 int *ptr ;
00471 float fact ;
00472
00473 ptr = (int*)data ;
00474 for(cnt=0 ; cnt<width*height*3 ; cnt++, ptr++){
00475 if(*ptr > max_val) max_val = *ptr ;
00476 }
00477
00478 fact = 255.0 / (float)max_val ;
00479
00480 ptr = (int*)data ;
00481 for(cnt=0 ; cnt<width*height*3 ; cnt++, ptr++){
00482 *ptr = (int)((float)(*ptr) * fact) ;
00483 }
00484
00485 return true ;
00486 }
00487
00488
00489 void ImageRGB::normalise_colourspace(int scale_factor)
00494 {
00495 unsigned int cnt ;
00496 int *ptr ;
00497 int tot ;
00498
00499 ptr = (int*)data ;
00500 for(cnt=0 ; cnt<width*height ; cnt++){
00501 tot = *ptr ;
00502 tot += *(ptr+1) ;
00503 tot += *(ptr+2) ;
00504
00505 if(tot > 0){
00506 *ptr *= scale_factor ;
00507 *(ptr++) /= tot ;
00508 *ptr *= scale_factor ;
00509 *(ptr++) /= tot ;
00510 *ptr *= scale_factor ;
00511 *(ptr++) /= tot ;
00512 }
00513 }
00514 }
00515
00516 void ImageRGB::quick_grey_and_scale_down(unsigned int scale_fact,
00517 ImageGrey& img)
00521 {
00522 unsigned int xcnt, ycnt ;
00523 PixelRGB* pix_ptr ;
00524 int* op_ptr ;
00525 int* val_ptr ;
00526
00527 op_ptr = img.brightness ;
00528 for(ycnt=0 ; ycnt<height ; ycnt+=scale_fact){
00529 pix_ptr = &(data[ycnt*width]) ;
00530 for(xcnt=0 ; xcnt<width ;
00531 xcnt+=scale_fact, op_ptr++, pix_ptr+=scale_fact){
00532 val_ptr = (int*)pix_ptr ;
00533 *op_ptr = *(val_ptr++) ;
00534 *op_ptr += *(val_ptr++) ;
00535 *op_ptr += *val_ptr ;
00536 *op_ptr /= 3 ;
00537 }
00538 }
00539 }
00540
00541 void ImageRGB::histogram_segment(Histogram &hist,
00542 float threshold,
00543 ImageRGB& result)
00550 {
00551 unsigned int cnt ;
00552 PixelRGB* pix_ptr ;
00553 PixelRGB* res_ptr ;
00554 PixelRGB p_true(255,255,255) ;
00555 PixelRGB p_false(0,0,0) ;
00556 float prob ;
00557
00558 for(cnt=0, pix_ptr=data, res_ptr=result.data ;
00559 cnt<width*height ; cnt++, pix_ptr++, res_ptr++){
00560 prob = hist.get_mapped_value((unsigned int*) pix_ptr);
00561 if(prob > threshold) *res_ptr = p_true ;
00562 else *res_ptr = p_false ;
00563 }
00564 }
00565
00566 void ImageRGB::histogram_segment(Histogram &hist,
00567 float threshold,
00568 bool* result)
00575 {
00576 unsigned int cnt ;
00577 PixelRGB* pix_ptr ;
00578 bool* res_ptr ;
00579 float prob ;
00580
00581 for(cnt=0, pix_ptr=data, res_ptr=result ;
00582 cnt<width*height ; cnt++, pix_ptr++, res_ptr++){
00583 prob = hist.get_mapped_value((unsigned int*) pix_ptr);
00584 if(prob > threshold) *res_ptr = true ;
00585 else *res_ptr = false ;
00586 }
00587 }
00588
00589
00590
00591
00592
00593