As of Monday morning, so this is the code we showed at Uncraftivism.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Frame.cpp Source File

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 }