Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Frame.cpp
00001 #include "stdafx.h" 00002 00003 #include "mbed.h" 00004 #include "ucam.h" 00005 #include "Frame.h" 00006 00007 extern Logger pcSerial; 00008 00009 Frame* Frame::m_frames[MAX_FRAMES]; // array of reusable frames 00010 00011 Frame::Frame() // don't construct Frame yourself - call allocFrame instead 00012 { 00013 m_pixels = NULL; 00014 m_width = 0; 00015 m_height = 0; 00016 m_pixelFormat = 0; 00017 m_deleted = true; 00018 m_numPixels = 0; 00019 m_bad = false; 00020 } 00021 00022 00023 Frame::~Frame() 00024 { 00025 if( m_pixels != NULL ) 00026 free( m_pixels ); 00027 00028 } 00029 00030 // static - initialise the array of frames - call once at app start time 00031 void Frame::initFrames() 00032 { 00033 for( int f = 0; f < MAX_FRAMES; f ++ ) 00034 m_frames[f] = NULL; 00035 } 00036 00037 //static - reuse an existing frame, or make a new one 00038 void Frame::allocFrame( Frame **frame, uint8_t pixelFormat, uint16_t width, uint16_t height, uint16_t frameSize ) 00039 { 00040 for( int f = 0; f < MAX_FRAMES; f ++ ) 00041 if( m_frames[f] == NULL ) 00042 { 00043 m_frames[f] = new Frame(); 00044 m_frames[f]->init( pixelFormat, width, height, frameSize ); 00045 *frame = m_frames[f]; 00046 00047 return; 00048 } 00049 else 00050 { 00051 if( m_frames[f]->m_deleted ) 00052 { 00053 m_frames[f]->init( pixelFormat, width, height, frameSize ); 00054 *frame = m_frames[f]; 00055 return; 00056 } 00057 00058 } 00059 00060 pcSerial.printf("No free frames!\r\n"); 00061 *frame = NULL; 00062 00063 } 00064 00065 //static - make an existing frame available for reuse 00066 void Frame::releaseFrame( Frame **frame ) 00067 { 00068 for( int f = 0; f < MAX_FRAMES; f ++ ) 00069 if( m_frames[f] == *frame ) 00070 { 00071 m_frames[f]->m_deleted = true; 00072 *frame = NULL; 00073 return; 00074 } 00075 } 00076 00077 //static - make a new frame with the same parameters as an existing one, alloc a pixel buffer, but do not initialise the pixels 00078 void Frame::cloneFrame( Frame **clone, Frame* original ) 00079 { 00080 allocFrame( clone, original->m_pixelFormat, original->m_width, original->m_height, original->m_frameSize ); 00081 00082 } 00083 00084 00085 void Frame::init( uint8_t pixelFormat, uint16_t width, uint16_t height, uint32_t frameSize ) 00086 { 00087 00088 if( m_frameSize != frameSize ) // keep the same pixel buffer if we can, to avoid fragmentation 00089 { 00090 free( m_pixels ); 00091 m_pixels = (uint8_t *) malloc( frameSize ); 00092 } 00093 00094 m_pixelFormat = pixelFormat; 00095 m_width = width; 00096 m_height = height; 00097 m_frameSize = frameSize; 00098 m_deleted = false; 00099 m_bad = false; 00100 00101 switch( m_pixelFormat ) 00102 { 00103 case UCAM_COLOUR_2_BIT_GREY: 00104 m_bitsPerPixel = 2; 00105 break; 00106 case UCAM_COLOUR_4_BIT_GREY: 00107 m_bitsPerPixel = 4; 00108 break; 00109 case UCAM_COLOUR_8_BIT_GREY: 00110 m_bitsPerPixel = 8; 00111 break; 00112 case UCAM_COLOUR_8_BIT_COLOUR: 00113 m_bitsPerPixel = 8; 00114 break; 00115 case UCAM_COLOUR_12_BIT_COLOR: 00116 m_bitsPerPixel = 16; 00117 break; 00118 case UCAM_COLOUR_16_BIT_COLOR: 00119 m_bitsPerPixel = 16; 00120 break; 00121 case UCAM_COLOUR_JPEG: 00122 default: 00123 m_bitsPerPixel = 16; // ?? not at all sure, but we are not using frames to handle jpegs right now 00124 break; 00125 } 00126 00127 m_numPixels = (8 * m_frameSize) / m_bitsPerPixel; 00128 } 00129 00130 uint16_t Frame::getPixel( uint32_t p ) 00131 { 00132 switch( m_bitsPerPixel ) 00133 { 00134 case 4: 00135 if( p & 1 ) 00136 return m_pixels[ p >> 1 ] & 0x0f; 00137 else 00138 return m_pixels[ p >> 1 ] >> 4; 00139 00140 00141 case 8: 00142 return m_pixels[ p ]; 00143 00144 case 16: 00145 default: 00146 return ((m_pixels[p<<1]) << 8) + m_pixels[1 + (p<<1) ]; // todo - check bytes order 00147 } 00148 } 00149 00150 void Frame::setPixel( uint32_t p, uint16_t val ) 00151 { 00152 switch( m_bitsPerPixel ) 00153 { 00154 case 4: 00155 if( p & 1 ) 00156 m_pixels[ p >> 1 ] = ( m_pixels[ p >> 1 ] & 0xf0) | (val & 0x0f); 00157 else 00158 m_pixels[ p >> 1 ] = ( m_pixels[ p >> 1 ] & 0x0f) | ((val & 0x0f) << 4 ); 00159 break; 00160 00161 case 8: 00162 m_pixels[ p ] = (uint8_t) val; 00163 break; 00164 case 16: 00165 default: 00166 m_pixels[p<<1] = val>>8; 00167 m_pixels[1 + (p<<1) ] = val & 0xff; 00168 break; 00169 } 00170 00171 00172 } 00173 00174 void Frame::writeToFile( char *filename ) 00175 { 00176 pcSerial.printf("writeToFile - %s\r\n", filename); 00177 00178 FILE *rawFile = fopen(filename, FILE_WRITE_STRING); // "w" or "wb" for Windows 00179 00180 fwrite( &m_pixelFormat, 1, 1, rawFile ); 00181 fwrite( &m_width, 1, 2, rawFile ); 00182 fwrite( &m_height, 1, 2, rawFile ); 00183 fwrite( &m_frameSize, 1, 4, rawFile ); 00184 00185 fwrite( m_pixels, 1, m_frameSize, rawFile ); 00186 00187 fclose( rawFile ); 00188 00189 } 00190 00191 // static 00192 void Frame::readFromFile( char *filename, Frame **frame ) 00193 { 00194 *frame = NULL; 00195 00196 pcSerial.printf("readFromFile - %s\r\n", filename); 00197 00198 FILE *rawFile = fopen(filename, FILE_READ_STRING); 00199 if( rawFile == NULL ) 00200 { 00201 pcSerial.printf("readFromFile - failed to open %s\r\n", filename); 00202 return; 00203 } 00204 00205 uint8_t pixelFormat; 00206 uint16_t width; 00207 uint16_t height; 00208 uint32_t frameSize; 00209 00210 if( 1 == fread( &pixelFormat, 1, 1, rawFile )) 00211 if( 2 == fread( &width, 1, 2, rawFile )) 00212 if( 2 == fread( &height, 1, 2, rawFile )) 00213 if( 4 == fread( &frameSize, 1, 4, rawFile )) 00214 { 00215 00216 allocFrame( frame, pixelFormat, width, height, frameSize ); 00217 00218 if( frameSize != fread( (*frame)->m_pixels, 1, frameSize, rawFile )) 00219 { 00220 releaseFrame( frame ); 00221 pcSerial.printf("readFromFile - bad size"); 00222 } 00223 } 00224 00225 fclose( rawFile ); 00226 00227 }
Generated on Wed Jul 27 2022 03:18:56 by
1.7.2