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
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "MicrosoftRCBMP_RT.h"
00042 #include <math.h>
00043
00044 MicrosoftRCBMP_RT::MicrosoftRCBMP_RT(const char *filename)
00045 {
00046
00047
00048
00049
00050
00051
00052
00053 set_filename(filename);
00054 FileSize = IMAGE_DATA_OFFSET_R;
00055 ImageWidth = 0;
00056 ImageHeight = 0;
00057 HorizResolution = 0;
00058 VertResolution = 0;
00059 file_pnt = NULL;
00060 raw_data = NULL;
00061 }
00062
00063 MicrosoftRCBMP_RT::~MicrosoftRCBMP_RT()
00064 {
00065
00066
00067
00068
00069
00070 delete raw_data;
00071 }
00072
00073 void MicrosoftRCBMP_RT::set_filename(const char *filename)
00074 {
00075
00076
00077
00078
00079
00080 strncpy(file_name, filename, MAX_FILENAME_LEN);
00081
00082
00083 file_name[MAX_FILENAME_LEN] = '\0';
00084 }
00085
00086 bool MicrosoftRCBMP_RT::read_byte(char *inp_chr)
00087 {
00088
00089
00090
00091
00092
00093
00094 bool ret_val = true ;
00095 int char_read;
00096 if(file_pnt == NULL){
00097
00098 ret_val = false ;
00099 }
00100 else if( (char_read = fgetc(file_pnt)) == EOF){
00101
00102 ret_val = false ;
00103 }
00104 else{
00105
00106 *inp_chr = (char) char_read ;
00107 }
00108 return ret_val ;
00109 }
00110
00111 bool MicrosoftRCBMP_RT::read_word(unsigned int *inp_word)
00112 {
00113
00114
00115
00116
00117
00118 unsigned char inp1;
00119 unsigned char inp2;
00120 bool ret_val = true ;
00121
00122 ret_val = read_byte((char *)(&inp1));
00123
00124 if(ret_val){
00125
00126 ret_val = read_byte((char *)(&inp2));
00127 }
00128
00129 if(ret_val){
00130
00131 *inp_word = inp1 + (((unsigned int)(inp2))<<8) ;
00132 }
00133
00134 return ret_val ;
00135 }
00136
00137 bool MicrosoftRCBMP_RT::read_dword(unsigned int *inp_word)
00138 {
00139
00140
00141
00142
00143
00144 unsigned char inp1;
00145 unsigned char inp2;
00146 unsigned char inp3;
00147 unsigned char inp4;
00148 bool ret_val = true ;
00149
00150 ret_val = read_byte((char *)(&inp1));
00151
00152 if(ret_val){
00153
00154 ret_val = read_byte((char *)(&inp2));
00155 }
00156
00157 if(ret_val){
00158
00159 ret_val = read_byte((char *)(&inp3));
00160 }
00161
00162 if(ret_val){
00163
00164 ret_val = read_byte((char *)(&inp4));
00165 }
00166
00167 if(ret_val){
00168
00169 *inp_word = (unsigned int)inp1 +
00170 (((unsigned int)(inp2))<<8) +
00171 (((unsigned int)(inp3))<<16) +
00172 (((unsigned int)(inp4))<<24) ;
00173 }
00174
00175 return ret_val ;
00176 }
00177
00178 bool MicrosoftRCBMP_RT::allocate_storage()
00179 {
00180
00181
00182
00183
00184 unsigned int storage_bytes_per_row;
00185
00186 storage_bytes_per_row = ImageWidth ;
00187
00188
00189 while(storage_bytes_per_row & 0x3){
00190
00191 storage_bytes_per_row++ ;
00192 }
00193
00194 raw_data = new unsigned char[storage_bytes_per_row * ImageHeight];
00195
00196 if(raw_data==NULL) return false;
00197 else return true;
00198 }
00199
00200 void MicrosoftRCBMP_RT::calculate_filesize()
00201 {
00202
00203
00204
00205
00206
00207 unsigned int bytes_per_row;
00208
00209 #if 0
00210 bytes_per_row = ImageWidth / 8 ;
00211
00212 if(ImageWidth & 0xF){
00213
00214 bytes_per_row++ ;
00215 }
00216
00217 while( bytes_per_row & 0x03 ){
00218
00219 bytes_per_row++ ;
00220 }
00221
00222 FileSize = bytes_per_row * ImageHeight + IMAGE_DATA_OFFSET_R ;
00223 #else
00224 bytes_per_row = ImageWidth ;
00225 while( bytes_per_row & 0x03 ){
00226
00227 bytes_per_row++ ;
00228 }
00229 FileSize = bytes_per_row * ImageHeight + IMAGE_DATA_OFFSET_R ;
00230 #endif
00231
00232 }
00233
00234 bool MicrosoftRCBMP_RT::read()
00235 {
00236
00237
00238
00239
00240 bool ret_val = true ;
00241 unsigned int bytes_in=0;
00242 unsigned char *d_pointer;
00243 char pad;
00244 unsigned int line;
00245 unsigned int pixel;
00246 unsigned int cnt;
00247
00248 if((file_pnt = fopen(file_name,"rb"))==NULL){
00249
00250 ret_val = false;
00251 }
00252 else{
00253
00254 ret_val &= read_byte(&type1);
00255 ret_val &= read_byte(&type2);
00256 ret_val &= read_dword(&FileSize);
00257 ret_val &= read_dword(&reserved);
00258 ret_val &= read_dword(&data_off);
00259 ret_val &= read_dword(&head_size);
00260 ret_val &= read_dword(&ImageWidth);
00261 ret_val &= read_dword(&ImageHeight);
00262 ret_val &= read_word(&no_planes);
00263 ret_val &= read_word(&bits_per_pixel);
00264 ret_val &= read_dword(&comp_method);
00265 ret_val &= read_dword(&bitmap_size);
00266 ret_val &= read_dword(&HorizResolution);
00267 ret_val &= read_dword(&VertResolution);
00268 ret_val &= read_dword(&no_cols);
00269 ret_val &= read_dword(&no_sig_cols);
00270
00271 if(ret_val){
00272
00273 palette = new rgb[no_cols] ;
00274 if(palette==NULL) ret_val = false ;
00275 }
00276
00277
00278 for(cnt=0 ; cnt<no_cols && ret_val ; cnt++){
00279 ret_val &= read_byte((char *)(&(palette[cnt].blue)));
00280 ret_val &= read_byte((char *)(&(palette[cnt].green)));
00281 ret_val &= read_byte((char *)(&(palette[cnt].red)));
00282 ret_val &= read_byte(&pad);
00283 }
00284 }
00285
00286 ret_val &= check_header_valid();
00287
00288 if(ret_val){
00289
00290 ret_val = allocate_storage();
00291 }
00292 if(ret_val){
00293
00294 d_pointer = raw_data ;
00295
00296 for(line=0 ; line<ImageHeight && ret_val ; line ++){
00297
00298 bytes_in = 0;
00299 for(pixel=0 ; pixel<ImageWidth && ret_val ; pixel ++){
00300 ret_val &= read_byte((char *)d_pointer++);
00301 bytes_in++;
00302 }
00303 }
00304 }
00305
00306 if( file_pnt == NULL ||
00307 fclose(file_pnt) == EOF ){
00308
00309 ret_val = false ;
00310 }
00311 return ret_val;
00312 }
00313
00314
00315
00316 bool MicrosoftRCBMP_RT::write()
00317 {
00318
00319
00320
00321
00322 bool ret_val = true ;
00323 unsigned int bytes_in=0;
00324 unsigned char *d_pointer;
00325 char pad=0;
00326 unsigned int line;
00327 unsigned int pixel;
00328 unsigned int cnt;
00329
00330 if((file_pnt = fopen(file_name,"wb"))==NULL){
00331
00332 ret_val = false;
00333 }
00334 else{
00335
00336 ret_val &= write_byte('B');
00337 ret_val &= write_byte('M');
00338 ret_val &= write_dword(FileSize);
00339 ret_val &= write_dword(0);
00340 ret_val &= write_dword(IMAGE_DATA_OFFSET_R);
00341 ret_val &= write_dword(HEADER_SIZE_R);
00342 ret_val &= write_dword(ImageWidth);
00343 ret_val &= write_dword(ImageHeight);
00344 ret_val &= write_word(NO_OF_IMAGE_PLANES_R);
00345 ret_val &= write_word(BITS_PER_PIXEL_R);
00346 ret_val &= write_dword(COMPRESSION_METHOD_R);
00347 ret_val &= write_dword(SIZE_OF_BITMAP_R);
00348 ret_val &= write_dword(HorizResolution);
00349 ret_val &= write_dword(VertResolution);
00350 ret_val &= write_dword(no_cols);
00351 ret_val &= write_dword(NO_SIGNIFICANT_COLS_R);
00352
00353
00354 for(cnt=0 ; cnt<no_cols && ret_val ; cnt++){
00355 ret_val &= write_byte((char)((palette[cnt].blue)));
00356 ret_val &= write_byte((char)((palette[cnt].green)));
00357 ret_val &= write_byte((char)((palette[cnt].red)));
00358 ret_val &= write_byte(pad);
00359 }
00360 }
00361
00362 if(ret_val){
00363
00364 d_pointer = raw_data ;
00365
00366 for(line=0 ; line<ImageHeight && ret_val ; line ++){
00367
00368 bytes_in = 0;
00369 for(pixel=0 ; pixel<ImageWidth && ret_val ; pixel ++){
00370 ret_val &= write_byte((char)*(d_pointer++));
00371 }
00372 }
00373 }
00374
00375 if( file_pnt == NULL ||
00376 fclose(file_pnt) == EOF ){
00377
00378 ret_val = false ;
00379 }
00380 return ret_val;
00381 }
00382
00383 bool MicrosoftRCBMP_RT::check_header_valid()
00384 {
00385
00386
00387
00388
00389 bool ret_val ;
00390
00391 if( type1 != 'B' ||
00392 type2 != 'M' ||
00393
00394 head_size != HEADER_SIZE_R ||
00395 no_planes != NO_OF_IMAGE_PLANES_R ||
00396 bits_per_pixel != BITS_PER_PIXEL_R ||
00397 comp_method != COMPRESSION_METHOD_R ){
00398
00399 ret_val = false ;
00400 }
00401 else{
00402 ret_val = true ;
00403 }
00404
00405 return ret_val ;
00406 }
00407
00408 bool MicrosoftRCBMP_RT::write_byte(char chr)
00409 {
00410
00411
00412
00413
00414
00415 bool ret_val = true ;
00416
00417 if(file_pnt == NULL){
00418
00419 ret_val = false ;
00420 }
00421 else if( fputc((int)chr, file_pnt) == EOF){
00422
00423 ret_val = false ;
00424 }
00425 else{
00426
00427 ret_val = true ;
00428 }
00429
00430 return ret_val ;
00431 }
00432
00433 bool MicrosoftRCBMP_RT::write_word(unsigned int wrd)
00434 {
00435
00436
00437
00438
00439
00440 unsigned int low_b;
00441 unsigned int hi_b;
00442 bool ret_val = true ;
00443
00444 low_b = wrd&0xFF ;
00445 hi_b = ( wrd >> 8 ) & 0xFF ;
00446
00447 ret_val = write_byte((int)low_b);
00448
00449 if(ret_val){
00450
00451 ret_val = write_byte((int)hi_b);
00452 }
00453
00454 return ret_val ;
00455 }
00456
00457 bool MicrosoftRCBMP_RT::write_dword(unsigned int wrd)
00458 {
00459
00460
00461
00462
00463
00464 char by1;
00465 char by2;
00466 char by3;
00467 char by4;
00468 bool ret_val = true ;
00469
00470 by1 = wrd&0xFF ;
00471 by2 = ( wrd >> 8 ) & 0xFF ;
00472 by3 = ( wrd >> 16 ) & 0xFF ;
00473 by4 = ( wrd >> 24 ) & 0xFF ;
00474 ret_val = write_byte(by1);
00475
00476 if(ret_val){
00477
00478 ret_val = write_byte(by2);
00479 }
00480
00481 if(ret_val){
00482
00483 ret_val = write_byte(by3);
00484 }
00485
00486 if(ret_val){
00487
00488 ret_val = write_byte(by4);
00489 }
00490
00491 return ret_val ;
00492 }
00493
00494
00495
00496 void MicrosoftRCBMP_RT::extract_data(int *rgb)
00497 {
00498
00499
00500
00501
00502
00503 unsigned int lines;
00504 unsigned int pixels;
00505
00506 unsigned char *buff_pnt = raw_data;
00507 unsigned int p_off;
00508 unsigned int bytes_per_line;
00509
00510
00511
00512 bytes_per_line = ImageWidth ;
00513
00514 while(bytes_per_line & 0x3){
00515
00516 bytes_per_line++;
00517 }
00518
00519 p_off = (ImageWidth*ImageHeight);
00520
00521 for(lines=0 ; lines<ImageHeight ; lines ++){
00522
00523
00524
00525 p_off -= ImageWidth ;
00526
00527
00528 for(pixels=0; pixels<ImageWidth ; pixels++){
00529
00530 rgb[p_off*3] = palette[*buff_pnt].red ;
00531 rgb[p_off*3+1] = palette[*buff_pnt].green ;
00532 rgb[p_off*3+2] = palette[*buff_pnt].blue ;
00533
00534 buff_pnt++;
00535 p_off++;
00536 }
00537 for(pixels=0; pixels<bytes_per_line-ImageWidth ; pixels++){
00538 buff_pnt++ ;
00539 }
00540
00541
00542 p_off -= ImageWidth ;
00543 }
00544 }
00545
00546 void MicrosoftRCBMP_RT::put_data(int *rgb)
00552 {
00553
00554 unsigned int lines;
00555 unsigned int pixels;
00556 unsigned char *buff_pnt = raw_data;
00557 unsigned int p_off;
00558 unsigned int bytes_per_line;
00559
00560 bytes_per_line = ImageWidth ;
00561
00562 while(bytes_per_line & 0x3){
00563
00564 bytes_per_line++;
00565 }
00566
00567 p_off = (ImageWidth*ImageHeight);
00568
00569 for(lines=0 ; lines<ImageHeight ; lines ++){
00570
00571
00572
00573 p_off -= ImageWidth ;
00574
00575
00576 for(pixels=0; pixels<ImageWidth ; pixels++){
00577
00578 *buff_pnt = palette_lookup(&(rgb[p_off*3])) ;
00579
00580 buff_pnt++;
00581 p_off++;
00582 }
00583 for(pixels=0; pixels<bytes_per_line-ImageWidth ; pixels++){
00584 buff_pnt++ ;
00585 }
00586
00587
00588 p_off -= ImageWidth ;
00589 }
00590 }
00591
00592
00593 void MicrosoftRCBMP_RT::put_data_grey(int *grey)
00599 {
00600
00601 unsigned int lines;
00602 unsigned int pixels;
00603 unsigned char *buff_pnt = raw_data;
00604 unsigned int p_off;
00605 unsigned int bytes_per_line;
00606 int rgb[3] ;
00607
00608 bytes_per_line = ImageWidth ;
00609
00610 while(bytes_per_line & 0x3){
00611
00612 bytes_per_line++;
00613 }
00614
00615 p_off = (ImageWidth*ImageHeight);
00616
00617 for(lines=0 ; lines<ImageHeight ; lines ++){
00618
00619
00620
00621 p_off -= ImageWidth ;
00622
00623
00624 for(pixels=0; pixels<ImageWidth ; pixels++){
00625
00626 rgb[0] = grey[p_off] ;
00627 rgb[1] = grey[p_off] ;
00628 rgb[2] = grey[p_off] ;
00629
00630 *buff_pnt = palette_lookup(rgb) ;
00631
00632 buff_pnt++;
00633 p_off++;
00634 }
00635 for(pixels=0; pixels<bytes_per_line-ImageWidth ; pixels++){
00636 buff_pnt++ ;
00637 }
00638
00639
00640 p_off -= ImageWidth ;
00641 }
00642 }
00643
00644 unsigned char MicrosoftRCBMP_RT::palette_lookup(int* rgb)
00648 {
00649 unsigned char rv = 0 ;
00650 unsigned int cnt ;
00651 float min_d=HUGE_VAL, d, dr, dg, db ;
00652
00653 for(cnt=0 ; cnt<no_cols ; cnt++){
00654 dr = (float)rgb[0] - (float)palette[cnt].red ;
00655 dg = (float)rgb[1] - (float)palette[cnt].green ;
00656 db = (float)rgb[2] - (float)palette[cnt].blue ;
00657
00658 d = dr*dr + dg*dg + db*db ;
00659 if(d < min_d){
00660 rv = cnt ;
00661 min_d = d ;
00662 }
00663 }
00664
00665 return rv ;
00666 }
00667
00668 bool MicrosoftRCBMP_RT::set_palette_grey256()
00669 {
00670 unsigned int cnt ;
00671
00672 no_cols = 256 ;
00673 if((palette = new rgb[256])==NULL) return false ;
00674
00675 for(cnt=0 ; cnt<255 ; cnt++){
00676 palette[cnt].red = cnt ;
00677 palette[cnt].green = cnt ;
00678 palette[cnt].blue = cnt ;
00679 }
00680
00681 return true ;
00682 }
00683
00684 bool MicrosoftRCBMP_RT::set_size(unsigned int width, unsigned int height)
00685 {
00686
00687
00688
00689
00690
00691
00692
00693 bool ret_val ;
00694
00695
00696 delete [] raw_data ;
00697
00698 ImageWidth = width ;
00699 ImageHeight = height ;
00700
00701 if(allocate_storage()){
00702
00703 ret_val = true ;
00704 }
00705 else{
00706 ret_val = false ;
00707 }
00708
00709 calculate_filesize();
00710
00711 return ret_val ;
00712 }
00713
00714
00715 void MicrosoftRCBMP_RT::extract_data_grey(int *grey)
00716 {
00717
00718
00719
00720
00721
00722 unsigned int lines;
00723 unsigned int pixels;
00724
00725 unsigned char *buff_pnt = raw_data;
00726 unsigned int p_off;
00727 unsigned int bytes_per_line;
00728
00729
00730
00731 bytes_per_line = ImageWidth ;
00732
00733 while(bytes_per_line & 0x3){
00734
00735 bytes_per_line++;
00736 }
00737
00738 p_off = (ImageWidth*ImageHeight);
00739
00740 for(lines=0 ; lines<ImageHeight ; lines ++){
00741
00742
00743
00744 p_off -= ImageWidth ;
00745
00746
00747 for(pixels=0; pixels<ImageWidth ; pixels++){
00748
00749 grey[p_off] = (int) (((palette[*buff_pnt].red +
00750 palette[*buff_pnt].green +
00751 palette[*buff_pnt].blue) / 3.0)+0.5) ;
00752
00753 buff_pnt++;
00754 p_off++;
00755 }
00756 for(pixels=0; pixels<bytes_per_line-ImageWidth ; pixels++){
00757 buff_pnt++ ;
00758 }
00759
00760
00761 p_off -= ImageWidth ;
00762 }
00763 }
00764