Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

MicrosoftRCBMP_RT.cpp

00001 /*****************************************************************************
00002  *
00003  * File :       MicrosoftRCBMP_RT.cpp
00004  *
00005  * Module :     ImageLib.a
00006  *
00007  * Author :     Derek Magee, School of Computer Science, Leeds University.
00008  *
00009  * Created :    3 November 1998
00010  *
00011  *****************************************************************************
00012  *
00013  * Source code for Image Library MkII
00014  *
00015  * The author, Derek Magee, gives permission for this code to be copied,
00016  * modified and distributed within the University of Leeds subject to the
00017  * following conditions:-
00018  *
00019  * - The code is not to be used for commercial gain.
00020  * - The code and use thereof will be attributed to the author where
00021  *   appropriate (inluding demonstrations which rely on it's use).
00022  * - All modified, distributions of the source files will retain this header.
00023  *
00024  *****************************************************************************
00025  *
00026  * Description:
00027  *
00028  * Methods for reading and writing monochrome Microsoft v3 bitmap files.
00029  *
00030  *****************************************************************************
00031  *
00032  * Revision History:
00033  *
00034  * Date         By              Revision
00035  *
00036  * 31/10/97     DRM             Created. (for original image library)
00037  * 17/02/04     DRM             Updated for libRTImage
00038  *
00039  ****************************************************************************/
00040 
00041 #include "MicrosoftRCBMP_RT.h"
00042 #include <math.h>
00043 
00044 MicrosoftRCBMP_RT::MicrosoftRCBMP_RT(const char *filename)
00045 {
00046 /* 
00047  * This is the constructor method for the MicrosoftRCBMP_RT class. It copies the
00048  * string pointed to by filename into the file_name buffer, truncating if
00049  * it is greater than this buffer and initialises other parameters to sensible
00050  * values.
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  * This is the destructor for the class MicrosoftRCBMP_RT. It frees allocated 
00067  * memory.
00068  */
00069 
00070     delete raw_data;
00071 }
00072 
00073 void MicrosoftRCBMP_RT::set_filename(const char *filename)
00074 {
00075 /* 
00076  * copy string pointed to by filename into buffer file_name truncating if
00077  * length is greater than MAX_FILENAME_LEN.
00078  */
00079 
00080     strncpy(file_name, filename, MAX_FILENAME_LEN);
00081 
00082     /* Ensure string is terminated if length = MAX_FILENAME_LEN */
00083     file_name[MAX_FILENAME_LEN] = '\0';
00084 }
00085 
00086 bool MicrosoftRCBMP_RT::read_byte(char *inp_chr)
00087 {
00088 /*
00089  * Reads a byte from stream pointed to by file_pnt into *inp_chr. Returns
00090  * false if cannot
00091  * read or invalid file pointer.
00092  */
00093 
00094     bool ret_val = true ;
00095     int char_read;
00096     if(file_pnt == NULL){
00097     /* Invalid file pointer */
00098         ret_val = false ;
00099     }
00100     else if( (char_read = fgetc(file_pnt)) == EOF){
00101     /* Could not read character from file */
00102         ret_val = false ;
00103     }
00104     else{
00105     /* Character read Ok */
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  * Reads a little endian word from stream pointed to by file_pnt into
00115  * *inp_word. Returns false if cannot read or invalid file pointer.
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     /* First byte read OK */
00126         ret_val = read_byte((char *)(&inp2));
00127     }
00128 
00129     if(ret_val){
00130     /* Both bytes read OK */
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  * Reads a little endian double word from stream pointed to by file_pnt into
00141  * *inp_word. Returns false if cannot read or invalid file pointer.
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     /* First byte read OK */
00154         ret_val = read_byte((char *)(&inp2));
00155     }
00156 
00157     if(ret_val){
00158     /* Second byte read OK */
00159         ret_val = read_byte((char *)(&inp3));
00160     }
00161 
00162     if(ret_val){
00163     /* Third byte read OK */
00164         ret_val = read_byte((char *)(&inp4));
00165     }
00166 
00167     if(ret_val){
00168     /* All 4 bytes read OK */
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  * Allocates memory for raw_data based on ImageWidth and ImageHeight.
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     /* Bytes per row is not divisible by 4 */
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  * Calculates the filesize from ImageWidth and ImageHeight and stores this in 
00204  * FileSize.
00205  */
00206 
00207     unsigned int bytes_per_row;
00208 
00209 #if 0
00210     bytes_per_row = ImageWidth / 8 ;
00211 
00212     if(ImageWidth & 0xF){
00213     /* Bits per row is not divisible by 8 */
00214         bytes_per_row++ ;
00215     }
00216 
00217     while( bytes_per_row & 0x03 ){
00218     /* Bytes per row is not divisible by 4 */
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     /* Bytes per row is not divisible by 4 */
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  * Method to read file data from file into the object 
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     /* Could not open file */
00250         ret_val = false;
00251     }
00252     else{
00253     /* Read in header info */
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         /* Allocate memory for palette */
00273             palette = new rgb[no_cols] ;
00274             if(palette==NULL) ret_val = false ;
00275         }
00276 
00277         /* Read in palette */
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     /* No problems so far */
00290        ret_val = allocate_storage();
00291     }
00292     if(ret_val){
00293     /* Read in data */
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     /* Error closing file */
00309         ret_val = false ;
00310     }
00311     return ret_val;
00312 }
00313         
00314 
00315 
00316 bool MicrosoftRCBMP_RT::write()
00317 {
00318 /*
00319  * Method to read file data from file into the object 
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     /* Could not open file */
00332         ret_val = false;
00333     }
00334     else{
00335     /* Read in header info */
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         /* Write palette */
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     /* Write data */
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     /* Error closing file */
00378         ret_val = false ;
00379     }
00380     return ret_val;
00381 }
00382  
00383 bool MicrosoftRCBMP_RT::check_header_valid()
00384 {
00385 /* 
00386  * Checks header of file is valid.
00387  */
00388 
00389     bool ret_val ;
00390 
00391     if( type1           != 'B'                  ||
00392         type2           != 'M'                  ||
00393 //        data_off        != IMAGE_DATA_OFFSET_R  ||
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     /* Bitmap file header is invalid */
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  * Writes a byte (chr) to stream pointed to by file_pnt. Returns
00412  * false if cannot write or invalid file pointer.
00413  */
00414 
00415     bool ret_val = true ;
00416 
00417     if(file_pnt == NULL){
00418     /* Invalid file pointer */
00419         ret_val = false ;
00420     }
00421     else if( fputc((int)chr, file_pnt) == EOF){
00422     /* Could not write character to file */
00423         ret_val = false ;
00424     }
00425     else{
00426     /* Character written Ok */
00427         ret_val = true ;
00428     }
00429 
00430     return ret_val ;
00431 }
00432 
00433 bool MicrosoftRCBMP_RT::write_word(unsigned int wrd)
00434 {
00435 /*
00436  *  Writes a little endian word (wrd) to stream pointed to by file_pnt.
00437  *  Returns false if cannot write or invalid file pointer.
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     /* First byte written OK */
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  * Writes a little endian double word to stream pointed to by file_pnt.
00461  * *inp_word. Returns false if cannot write or invalid file pointer.
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     /* First byte writtten OK */
00478         ret_val = write_byte(by2);
00479     }
00480 
00481     if(ret_val){
00482     /* Second byte written OK */
00483         ret_val = write_byte(by3);
00484     }
00485 
00486     if(ret_val){
00487     /* Third byte written OK */
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  * Converts raw data from raw_data to RGB in the buffer rgb.
00500  * Note: Also flips the image vertically as bitmaps are stored upsidedown.
00501  */
00502 
00503     unsigned int  lines;
00504     unsigned int  pixels;
00505     //unsigned int  bytes_read;
00506     unsigned char *buff_pnt = raw_data;
00507     unsigned int  p_off;
00508     unsigned int  bytes_per_line;
00509     //unsigned char bitmask = 0x80;
00510     //int           *rgb_ptr ;
00511 
00512     bytes_per_line = ImageWidth ;
00513 
00514     while(bytes_per_line & 0x3){
00515     /* Bytes per line is not divisible by 4 */
00516         bytes_per_line++;
00517     }
00518    
00519     p_off = (ImageWidth*ImageHeight);
00520  
00521     for(lines=0 ; lines<ImageHeight ; lines ++){
00522     /* For each line in the image */
00523 
00524         /* Set pointer to beginning of previous line */
00525         p_off -= ImageWidth ;
00526 
00527         /* Loop through pixels in the line */
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         /* Set pointer to beginning of current line */
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     /* Bytes per line is not divisible by 4 */
00564         bytes_per_line++;
00565     }
00566 
00567     p_off = (ImageWidth*ImageHeight);
00568 
00569     for(lines=0 ; lines<ImageHeight ; lines ++){
00570     /* For each line in the image */
00571 
00572         /* Set pointer to beginning of previous line */
00573         p_off -= ImageWidth ;
00574 
00575         /* Loop through pixels in the line */
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         /* Set pointer to beginning of current line */
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     /* Bytes per line is not divisible by 4 */
00612         bytes_per_line++;
00613     }
00614 
00615     p_off = (ImageWidth*ImageHeight);
00616 
00617     for(lines=0 ; lines<ImageHeight ; lines ++){
00618     /* For each line in the image */
00619 
00620         /* Set pointer to beginning of previous line */
00621         p_off -= ImageWidth ;
00622 
00623         /* Loop through pixels in the line */
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         /* Set pointer to beginning of current line */
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  * Method sets the parameters ImageWidth and ImageHeight to width and height
00688  * and ensures that the memory allocated to raw_data is large enough to contain
00689  * this ammount of data. The method returns false if memory allocation is
00690  * unsuccessful and true otherwise.
00691  */
00692 
00693     bool ret_val ;
00694 
00695     /* First free memory currently associated with raw_data (if any) */
00696     delete [] raw_data ;
00697 
00698     ImageWidth = width ;
00699     ImageHeight = height ;
00700 
00701     if(allocate_storage()){
00702     /* memory allocation was sucessful */
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  * Converts raw data from raw_data to RGB in the buffer rgb.
00719  * Note: Also flips the image vertically as bitmaps are stored upsidedown.
00720  */
00721 
00722     unsigned int  lines;
00723     unsigned int  pixels;
00724     //unsigned int  bytes_read;
00725     unsigned char *buff_pnt = raw_data;
00726     unsigned int  p_off;
00727     unsigned int  bytes_per_line;
00728     //unsigned char bitmask = 0x80;
00729     //int           *rgb_ptr ;
00730 
00731     bytes_per_line = ImageWidth ;
00732 
00733     while(bytes_per_line & 0x3){
00734     /* Bytes per line is not divisible by 4 */
00735         bytes_per_line++;
00736     }
00737 
00738     p_off = (ImageWidth*ImageHeight);
00739 
00740     for(lines=0 ; lines<ImageHeight ; lines ++){
00741     /* For each line in the image */
00742 
00743         /* Set pointer to beginning of previous line */
00744         p_off -= ImageWidth ;
00745 
00746         /* Loop through pixels in the line */
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         /* Set pointer to beginning of current line */
00761         p_off -= ImageWidth ;
00762     }
00763 }
00764 

Generated at Fri Aug 13 17:29:21 2004 for libRTImage by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001