This is a code which generates the various zoomed versions of an image stored in an SD card and displays it on a Nokia LCD based on the keys pressed on a capacitive touch pad.
Dependencies: FatFileSystem mbed
Fork of Lab3 by
myBMP/myBMP.cpp@1:6048138606a0, 2012-10-11 (annotated)
- Committer:
- abarve9
- Date:
- Thu Oct 11 06:10:31 2012 +0000
- Revision:
- 1:6048138606a0
- Parent:
- 0:c546b51ecf0b
This is an image zooming program which reads an image stored in an SD card and displays the various zoomed versions of the image based on the key pressed in the capacitive touch sensor.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
XkLi | 0:c546b51ecf0b | 1 | #include "myBMP.h" |
XkLi | 0:c546b51ecf0b | 2 | |
XkLi | 0:c546b51ecf0b | 3 | int BitDepth = 1; |
XkLi | 0:c546b51ecf0b | 4 | int Width = 1; |
XkLi | 0:c546b51ecf0b | 5 | int Height = 1; |
XkLi | 0:c546b51ecf0b | 6 | RGBApixel *Colors; |
XkLi | 0:c546b51ecf0b | 7 | |
XkLi | 0:c546b51ecf0b | 8 | bool SafeFread( char* buffer, int size, int number, FILE* fp ) |
XkLi | 0:c546b51ecf0b | 9 | { |
XkLi | 0:c546b51ecf0b | 10 | using namespace std; |
XkLi | 0:c546b51ecf0b | 11 | int ItemsRead; |
XkLi | 0:c546b51ecf0b | 12 | if( feof(fp) ) |
XkLi | 0:c546b51ecf0b | 13 | { return false; } |
XkLi | 0:c546b51ecf0b | 14 | ItemsRead = (int) fread( buffer , size , number , fp ); |
XkLi | 0:c546b51ecf0b | 15 | if( ItemsRead < number ) |
XkLi | 0:c546b51ecf0b | 16 | { return false; } |
XkLi | 0:c546b51ecf0b | 17 | return true; |
XkLi | 0:c546b51ecf0b | 18 | } |
XkLi | 0:c546b51ecf0b | 19 | |
XkLi | 0:c546b51ecf0b | 20 | bool Read32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) |
XkLi | 0:c546b51ecf0b | 21 | { |
XkLi | 0:c546b51ecf0b | 22 | int i; |
XkLi | 0:c546b51ecf0b | 23 | char Colors[4]; |
XkLi | 0:c546b51ecf0b | 24 | if( Width*4 > BufferSize ) |
XkLi | 0:c546b51ecf0b | 25 | { return false; } |
XkLi | 0:c546b51ecf0b | 26 | for( i=0 ; i < Width ; i++ ) |
XkLi | 0:c546b51ecf0b | 27 | { |
XkLi | 0:c546b51ecf0b | 28 | memcpy( (char*) &(Colors), (char*) Buffer+4*i, 4 ); |
XkLi | 0:c546b51ecf0b | 29 | //Blue, Green, Red, Alpha |
XkLi | 0:c546b51ecf0b | 30 | int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); |
XkLi | 0:c546b51ecf0b | 31 | (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); |
XkLi | 0:c546b51ecf0b | 32 | } |
XkLi | 0:c546b51ecf0b | 33 | return true; |
XkLi | 0:c546b51ecf0b | 34 | } |
XkLi | 0:c546b51ecf0b | 35 | |
XkLi | 0:c546b51ecf0b | 36 | bool Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) |
XkLi | 0:c546b51ecf0b | 37 | { |
XkLi | 0:c546b51ecf0b | 38 | int i; |
XkLi | 0:c546b51ecf0b | 39 | char Colors[4]; |
XkLi | 0:c546b51ecf0b | 40 | if( Width*3 > BufferSize ) |
XkLi | 0:c546b51ecf0b | 41 | { return false; } |
XkLi | 0:c546b51ecf0b | 42 | for( i=0 ; i < Width ; i++ ) |
XkLi | 0:c546b51ecf0b | 43 | { |
XkLi | 0:c546b51ecf0b | 44 | memcpy( (char*) &(Colors), (char*) Buffer+3*i, 3 ); |
XkLi | 0:c546b51ecf0b | 45 | //Blue, Green, Red, Alpha |
XkLi | 0:c546b51ecf0b | 46 | int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); |
XkLi | 0:c546b51ecf0b | 47 | (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); |
XkLi | 0:c546b51ecf0b | 48 | } |
XkLi | 0:c546b51ecf0b | 49 | return true; |
XkLi | 0:c546b51ecf0b | 50 | } |
XkLi | 0:c546b51ecf0b | 51 | |
XkLi | 0:c546b51ecf0b | 52 | RGBApixel GetColor( int ColorNumber) |
XkLi | 0:c546b51ecf0b | 53 | { |
XkLi | 0:c546b51ecf0b | 54 | RGBApixel Output; |
XkLi | 0:c546b51ecf0b | 55 | Output.Red = 255; |
XkLi | 0:c546b51ecf0b | 56 | Output.Green = 255; |
XkLi | 0:c546b51ecf0b | 57 | Output.Blue = 255; |
XkLi | 0:c546b51ecf0b | 58 | Output.Alpha = 0; |
XkLi | 0:c546b51ecf0b | 59 | |
XkLi | 0:c546b51ecf0b | 60 | if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) |
XkLi | 0:c546b51ecf0b | 61 | { |
XkLi | 0:c546b51ecf0b | 62 | return Output; |
XkLi | 0:c546b51ecf0b | 63 | } |
XkLi | 0:c546b51ecf0b | 64 | if( !Colors ) |
XkLi | 0:c546b51ecf0b | 65 | { |
XkLi | 0:c546b51ecf0b | 66 | return Output; |
XkLi | 0:c546b51ecf0b | 67 | } |
XkLi | 0:c546b51ecf0b | 68 | Output = Colors[ColorNumber]; |
XkLi | 0:c546b51ecf0b | 69 | return Output; |
XkLi | 0:c546b51ecf0b | 70 | } |
XkLi | 0:c546b51ecf0b | 71 | |
XkLi | 0:c546b51ecf0b | 72 | bool Read8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) |
XkLi | 0:c546b51ecf0b | 73 | { |
XkLi | 0:c546b51ecf0b | 74 | int i; |
XkLi | 0:c546b51ecf0b | 75 | if( Width > BufferSize ) |
XkLi | 0:c546b51ecf0b | 76 | { return false; } |
XkLi | 0:c546b51ecf0b | 77 | for( i=0 ; i < Width ; i++ ) |
XkLi | 0:c546b51ecf0b | 78 | { |
XkLi | 0:c546b51ecf0b | 79 | int Index = Buffer[i]; |
XkLi | 0:c546b51ecf0b | 80 | //Blue, Green, Red, Alpha |
XkLi | 0:c546b51ecf0b | 81 | RGBApixel colors = GetColor(Index); |
XkLi | 0:c546b51ecf0b | 82 | int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); |
XkLi | 0:c546b51ecf0b | 83 | (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); |
XkLi | 0:c546b51ecf0b | 84 | } |
XkLi | 0:c546b51ecf0b | 85 | return true; |
XkLi | 0:c546b51ecf0b | 86 | } |
XkLi | 0:c546b51ecf0b | 87 | |
XkLi | 0:c546b51ecf0b | 88 | bool Read4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) |
XkLi | 0:c546b51ecf0b | 89 | { |
XkLi | 0:c546b51ecf0b | 90 | int Shifts[2] = {4 ,0 }; |
XkLi | 0:c546b51ecf0b | 91 | int Masks[2] = {240,15}; |
XkLi | 0:c546b51ecf0b | 92 | |
XkLi | 0:c546b51ecf0b | 93 | int i=0; |
XkLi | 0:c546b51ecf0b | 94 | int j; |
XkLi | 0:c546b51ecf0b | 95 | int k=0; |
XkLi | 0:c546b51ecf0b | 96 | if( Width > 2*BufferSize ) |
XkLi | 0:c546b51ecf0b | 97 | { return false; } |
XkLi | 0:c546b51ecf0b | 98 | while( i < Width ) |
XkLi | 0:c546b51ecf0b | 99 | { |
XkLi | 0:c546b51ecf0b | 100 | j=0; |
XkLi | 0:c546b51ecf0b | 101 | while( j < 2 && i < Width ) |
XkLi | 0:c546b51ecf0b | 102 | { |
XkLi | 0:c546b51ecf0b | 103 | int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); |
XkLi | 0:c546b51ecf0b | 104 | RGBApixel colors = GetColor(Index); |
XkLi | 0:c546b51ecf0b | 105 | int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); |
XkLi | 0:c546b51ecf0b | 106 | (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); |
XkLi | 0:c546b51ecf0b | 107 | i++; j++; |
XkLi | 0:c546b51ecf0b | 108 | } |
XkLi | 0:c546b51ecf0b | 109 | k++; |
XkLi | 0:c546b51ecf0b | 110 | } |
XkLi | 0:c546b51ecf0b | 111 | return true; |
XkLi | 0:c546b51ecf0b | 112 | } |
XkLi | 0:c546b51ecf0b | 113 | bool Read1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) |
XkLi | 0:c546b51ecf0b | 114 | { |
XkLi | 0:c546b51ecf0b | 115 | int Shifts[8] = {7 ,6 ,5 ,4 ,3,2,1,0}; |
XkLi | 0:c546b51ecf0b | 116 | int Masks[8] = {128,64,32,16,8,4,2,1}; |
XkLi | 0:c546b51ecf0b | 117 | |
XkLi | 0:c546b51ecf0b | 118 | int i=0; |
XkLi | 0:c546b51ecf0b | 119 | int j; |
XkLi | 0:c546b51ecf0b | 120 | int k=0; |
XkLi | 0:c546b51ecf0b | 121 | |
XkLi | 0:c546b51ecf0b | 122 | if( Width > 8*BufferSize ) |
XkLi | 0:c546b51ecf0b | 123 | { return false; } |
XkLi | 0:c546b51ecf0b | 124 | while( i < Width ) |
XkLi | 0:c546b51ecf0b | 125 | { |
XkLi | 0:c546b51ecf0b | 126 | j=0; |
XkLi | 0:c546b51ecf0b | 127 | while( j < 8 && i < Width ) |
XkLi | 0:c546b51ecf0b | 128 | { |
XkLi | 0:c546b51ecf0b | 129 | int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); |
XkLi | 0:c546b51ecf0b | 130 | RGBApixel colors = GetColor(Index); |
XkLi | 0:c546b51ecf0b | 131 | int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); |
XkLi | 0:c546b51ecf0b | 132 | (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); |
XkLi | 0:c546b51ecf0b | 133 | i++; j++; |
XkLi | 0:c546b51ecf0b | 134 | } |
XkLi | 0:c546b51ecf0b | 135 | k++; |
XkLi | 0:c546b51ecf0b | 136 | } |
XkLi | 0:c546b51ecf0b | 137 | return true; |
XkLi | 0:c546b51ecf0b | 138 | } |
XkLi | 0:c546b51ecf0b | 139 | |
XkLi | 0:c546b51ecf0b | 140 | int TellNumberOfColors( int BitDepth ) |
XkLi | 0:c546b51ecf0b | 141 | { |
XkLi | 0:c546b51ecf0b | 142 | int output = 1 << BitDepth; |
XkLi | 0:c546b51ecf0b | 143 | if( BitDepth == 32 ) |
XkLi | 0:c546b51ecf0b | 144 | { output = 1 << 24; } |
XkLi | 0:c546b51ecf0b | 145 | return output; |
XkLi | 0:c546b51ecf0b | 146 | } |
XkLi | 0:c546b51ecf0b | 147 | |
XkLi | 0:c546b51ecf0b | 148 | bool ReadBMPFromFile( const char* FileName, RGBApixel *Colors, NokiaLCD *lcd) |
XkLi | 0:c546b51ecf0b | 149 | { |
XkLi | 0:c546b51ecf0b | 150 | FILE* fp = fopen( FileName, "rb" ); |
XkLi | 0:c546b51ecf0b | 151 | if( fp == NULL ) |
XkLi | 0:c546b51ecf0b | 152 | { |
XkLi | 0:c546b51ecf0b | 153 | return false; |
XkLi | 0:c546b51ecf0b | 154 | } |
XkLi | 0:c546b51ecf0b | 155 | |
XkLi | 0:c546b51ecf0b | 156 | // read the file header |
XkLi | 0:c546b51ecf0b | 157 | |
XkLi | 0:c546b51ecf0b | 158 | BMFH bmfh; |
XkLi | 0:c546b51ecf0b | 159 | bool NotCorrupted = true; |
XkLi | 0:c546b51ecf0b | 160 | |
XkLi | 0:c546b51ecf0b | 161 | NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp); |
XkLi | 0:c546b51ecf0b | 162 | |
XkLi | 0:c546b51ecf0b | 163 | bool IsBitmap = false; |
XkLi | 0:c546b51ecf0b | 164 | |
XkLi | 0:c546b51ecf0b | 165 | if( bmfh.bfType == 19778 ) |
XkLi | 0:c546b51ecf0b | 166 | { IsBitmap = true; } |
XkLi | 0:c546b51ecf0b | 167 | |
XkLi | 0:c546b51ecf0b | 168 | if( !IsBitmap ) |
XkLi | 0:c546b51ecf0b | 169 | { |
XkLi | 0:c546b51ecf0b | 170 | fclose( fp ); |
XkLi | 0:c546b51ecf0b | 171 | return false; |
XkLi | 0:c546b51ecf0b | 172 | } |
XkLi | 0:c546b51ecf0b | 173 | |
XkLi | 0:c546b51ecf0b | 174 | NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); |
XkLi | 0:c546b51ecf0b | 175 | NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp); |
XkLi | 0:c546b51ecf0b | 176 | NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp); |
XkLi | 0:c546b51ecf0b | 177 | NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 178 | |
XkLi | 0:c546b51ecf0b | 179 | // read the info header |
XkLi | 0:c546b51ecf0b | 180 | |
XkLi | 0:c546b51ecf0b | 181 | BMIH bmih; |
XkLi | 0:c546b51ecf0b | 182 | |
XkLi | 0:c546b51ecf0b | 183 | NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 184 | NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 185 | NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 186 | NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); |
XkLi | 0:c546b51ecf0b | 187 | NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp); |
XkLi | 0:c546b51ecf0b | 188 | |
XkLi | 0:c546b51ecf0b | 189 | NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 190 | NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 191 | NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 192 | NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 193 | NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 194 | NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp); |
XkLi | 0:c546b51ecf0b | 195 | |
XkLi | 0:c546b51ecf0b | 196 | // a safety catch: if any of the header information didn't read properly, abort |
XkLi | 0:c546b51ecf0b | 197 | // future idea: check to see if at least most is self-consistent |
XkLi | 0:c546b51ecf0b | 198 | |
XkLi | 0:c546b51ecf0b | 199 | if( !NotCorrupted ) |
XkLi | 0:c546b51ecf0b | 200 | { |
XkLi | 0:c546b51ecf0b | 201 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 202 | return false; |
XkLi | 0:c546b51ecf0b | 203 | } |
XkLi | 0:c546b51ecf0b | 204 | |
XkLi | 0:c546b51ecf0b | 205 | // if bmih.biCompression 1 or 2, then the file is RLE compressed |
XkLi | 0:c546b51ecf0b | 206 | |
XkLi | 0:c546b51ecf0b | 207 | if( bmih.biCompression == 1 || bmih.biCompression == 2 ) |
XkLi | 0:c546b51ecf0b | 208 | { |
XkLi | 0:c546b51ecf0b | 209 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 210 | return false; |
XkLi | 0:c546b51ecf0b | 211 | } |
XkLi | 0:c546b51ecf0b | 212 | |
XkLi | 0:c546b51ecf0b | 213 | // if bmih.biCompression > 3, then something strange is going on |
XkLi | 0:c546b51ecf0b | 214 | // it's probably an OS2 bitmap file. |
XkLi | 0:c546b51ecf0b | 215 | |
XkLi | 0:c546b51ecf0b | 216 | if( bmih.biCompression > 3 ) |
XkLi | 0:c546b51ecf0b | 217 | { |
XkLi | 0:c546b51ecf0b | 218 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 219 | return false; |
XkLi | 0:c546b51ecf0b | 220 | } |
XkLi | 0:c546b51ecf0b | 221 | |
XkLi | 0:c546b51ecf0b | 222 | if( bmih.biCompression == 3 && bmih.biBitCount != 16 ) |
XkLi | 0:c546b51ecf0b | 223 | { |
XkLi | 0:c546b51ecf0b | 224 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 225 | return false; |
XkLi | 0:c546b51ecf0b | 226 | } |
XkLi | 0:c546b51ecf0b | 227 | |
XkLi | 0:c546b51ecf0b | 228 | // set the bit depth |
XkLi | 0:c546b51ecf0b | 229 | |
XkLi | 0:c546b51ecf0b | 230 | int TempBitDepth = (int) bmih.biBitCount; |
XkLi | 0:c546b51ecf0b | 231 | if( TempBitDepth != 1 && TempBitDepth != 4 |
XkLi | 0:c546b51ecf0b | 232 | && TempBitDepth != 8 && TempBitDepth != 16 |
XkLi | 0:c546b51ecf0b | 233 | && TempBitDepth != 24 && TempBitDepth != 32 ) |
XkLi | 0:c546b51ecf0b | 234 | { |
XkLi | 0:c546b51ecf0b | 235 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 236 | return false; |
XkLi | 0:c546b51ecf0b | 237 | } |
XkLi | 0:c546b51ecf0b | 238 | BitDepth = (int)bmih.biBitCount; |
XkLi | 0:c546b51ecf0b | 239 | // set the size |
XkLi | 0:c546b51ecf0b | 240 | |
XkLi | 0:c546b51ecf0b | 241 | if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) |
XkLi | 0:c546b51ecf0b | 242 | { |
XkLi | 0:c546b51ecf0b | 243 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 244 | return false; |
XkLi | 0:c546b51ecf0b | 245 | } |
XkLi | 0:c546b51ecf0b | 246 | Width = (int) bmih.biWidth; |
XkLi | 0:c546b51ecf0b | 247 | Height = (int) bmih.biHeight; |
XkLi | 0:c546b51ecf0b | 248 | // some preliminaries |
XkLi | 0:c546b51ecf0b | 249 | |
XkLi | 0:c546b51ecf0b | 250 | double dBytesPerPixel = ( (double) BitDepth ) / 8.0; |
XkLi | 0:c546b51ecf0b | 251 | double dBytesPerRow = dBytesPerPixel * (Width+0.0); |
XkLi | 0:c546b51ecf0b | 252 | dBytesPerRow = ceil(dBytesPerRow); |
XkLi | 0:c546b51ecf0b | 253 | |
XkLi | 0:c546b51ecf0b | 254 | int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4; |
XkLi | 0:c546b51ecf0b | 255 | if( BytePaddingPerRow == 4 ) |
XkLi | 0:c546b51ecf0b | 256 | { BytePaddingPerRow = 0; } |
XkLi | 0:c546b51ecf0b | 257 | |
XkLi | 0:c546b51ecf0b | 258 | // if < 16 bits, read the palette |
XkLi | 0:c546b51ecf0b | 259 | |
XkLi | 0:c546b51ecf0b | 260 | if( BitDepth < 16 ) |
XkLi | 0:c546b51ecf0b | 261 | { |
XkLi | 0:c546b51ecf0b | 262 | // determine the number of colors specified in the |
XkLi | 0:c546b51ecf0b | 263 | // color table |
XkLi | 0:c546b51ecf0b | 264 | |
XkLi | 0:c546b51ecf0b | 265 | int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4; |
XkLi | 0:c546b51ecf0b | 266 | if( NumberOfColorsToRead > (1 << BitDepth) ) |
XkLi | 0:c546b51ecf0b | 267 | { NumberOfColorsToRead = (1 << BitDepth); } |
XkLi | 0:c546b51ecf0b | 268 | |
XkLi | 0:c546b51ecf0b | 269 | int n; |
XkLi | 0:c546b51ecf0b | 270 | for( n=0; n < NumberOfColorsToRead ; n++ ) |
XkLi | 0:c546b51ecf0b | 271 | { |
XkLi | 0:c546b51ecf0b | 272 | SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp); |
XkLi | 0:c546b51ecf0b | 273 | } |
XkLi | 0:c546b51ecf0b | 274 | for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ ) |
XkLi | 0:c546b51ecf0b | 275 | { |
XkLi | 0:c546b51ecf0b | 276 | RGBApixel WHITE; |
XkLi | 0:c546b51ecf0b | 277 | WHITE.Red = 255; |
XkLi | 0:c546b51ecf0b | 278 | WHITE.Green = 255; |
XkLi | 0:c546b51ecf0b | 279 | WHITE.Blue = 255; |
XkLi | 0:c546b51ecf0b | 280 | WHITE.Alpha = 0; |
XkLi | 0:c546b51ecf0b | 281 | Colors[n] = WHITE; |
XkLi | 0:c546b51ecf0b | 282 | } |
XkLi | 0:c546b51ecf0b | 283 | } |
XkLi | 0:c546b51ecf0b | 284 | |
XkLi | 0:c546b51ecf0b | 285 | // skip blank data if bfOffBits so indicates |
XkLi | 0:c546b51ecf0b | 286 | |
XkLi | 0:c546b51ecf0b | 287 | int BytesToSkip = bmfh.bfOffBits - 54;; |
XkLi | 0:c546b51ecf0b | 288 | if( BitDepth < 16 ) |
XkLi | 0:c546b51ecf0b | 289 | { BytesToSkip -= 4*(1 << BitDepth); } |
XkLi | 0:c546b51ecf0b | 290 | if( BitDepth == 16 && bmih.biCompression == 3 ) |
XkLi | 0:c546b51ecf0b | 291 | { BytesToSkip -= 3*4; } |
XkLi | 0:c546b51ecf0b | 292 | if( BytesToSkip < 0 ) |
XkLi | 0:c546b51ecf0b | 293 | { BytesToSkip = 0; } |
XkLi | 0:c546b51ecf0b | 294 | if( BytesToSkip > 0 && BitDepth != 16 ) |
XkLi | 0:c546b51ecf0b | 295 | { |
XkLi | 0:c546b51ecf0b | 296 | ebmpBYTE* TempSkipBYTE; |
XkLi | 0:c546b51ecf0b | 297 | TempSkipBYTE = new ebmpBYTE [BytesToSkip]; |
XkLi | 0:c546b51ecf0b | 298 | SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); |
XkLi | 0:c546b51ecf0b | 299 | delete [] TempSkipBYTE; |
XkLi | 0:c546b51ecf0b | 300 | } |
XkLi | 0:c546b51ecf0b | 301 | |
XkLi | 0:c546b51ecf0b | 302 | // This code reads 1, 4, 8, 24, and 32-bpp files |
XkLi | 0:c546b51ecf0b | 303 | // with a more-efficient buffered technique. |
XkLi | 0:c546b51ecf0b | 304 | |
XkLi | 0:c546b51ecf0b | 305 | int i,j; |
XkLi | 0:c546b51ecf0b | 306 | if( BitDepth != 16 ) |
XkLi | 0:c546b51ecf0b | 307 | { |
XkLi | 0:c546b51ecf0b | 308 | int BufferSize = (int) ( (Width*BitDepth) / 8.0 ); |
XkLi | 0:c546b51ecf0b | 309 | while( 8*BufferSize < Width*BitDepth ) |
XkLi | 0:c546b51ecf0b | 310 | { BufferSize++; } |
XkLi | 0:c546b51ecf0b | 311 | while( BufferSize % 4 ) |
XkLi | 0:c546b51ecf0b | 312 | { BufferSize++; } |
XkLi | 0:c546b51ecf0b | 313 | ebmpBYTE* Buffer; |
XkLi | 0:c546b51ecf0b | 314 | Buffer = new ebmpBYTE [BufferSize]; |
XkLi | 0:c546b51ecf0b | 315 | j= Height-1; |
XkLi | 0:c546b51ecf0b | 316 | while( j > -1 ) |
XkLi | 0:c546b51ecf0b | 317 | { |
XkLi | 0:c546b51ecf0b | 318 | int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp ); |
XkLi | 0:c546b51ecf0b | 319 | if( BytesRead < BufferSize ) |
XkLi | 0:c546b51ecf0b | 320 | { |
XkLi | 0:c546b51ecf0b | 321 | j = -1; |
XkLi | 0:c546b51ecf0b | 322 | } |
XkLi | 0:c546b51ecf0b | 323 | else |
XkLi | 0:c546b51ecf0b | 324 | { |
XkLi | 0:c546b51ecf0b | 325 | bool Success = false; |
XkLi | 0:c546b51ecf0b | 326 | if( BitDepth == 1 ) |
XkLi | 0:c546b51ecf0b | 327 | { Success = Read1bitRow( Buffer, BufferSize, j , lcd); } |
XkLi | 0:c546b51ecf0b | 328 | if( BitDepth == 4 ) |
XkLi | 0:c546b51ecf0b | 329 | { Success = Read4bitRow( Buffer, BufferSize, j , lcd); } |
XkLi | 0:c546b51ecf0b | 330 | if( BitDepth == 8 ) |
XkLi | 0:c546b51ecf0b | 331 | { Success = Read8bitRow( Buffer, BufferSize, j , lcd); } |
XkLi | 0:c546b51ecf0b | 332 | if( BitDepth == 24 ) |
XkLi | 0:c546b51ecf0b | 333 | { Success = Read24bitRow( Buffer, BufferSize, j , lcd); } |
XkLi | 0:c546b51ecf0b | 334 | if( BitDepth == 32 ) |
XkLi | 0:c546b51ecf0b | 335 | { Success = Read32bitRow( Buffer, BufferSize, j , lcd); } |
XkLi | 0:c546b51ecf0b | 336 | if( !Success ) |
XkLi | 0:c546b51ecf0b | 337 | { |
XkLi | 0:c546b51ecf0b | 338 | j = -1; |
XkLi | 0:c546b51ecf0b | 339 | } |
XkLi | 0:c546b51ecf0b | 340 | } |
XkLi | 0:c546b51ecf0b | 341 | j--; |
XkLi | 0:c546b51ecf0b | 342 | } |
XkLi | 0:c546b51ecf0b | 343 | delete [] Buffer; |
XkLi | 0:c546b51ecf0b | 344 | } |
XkLi | 0:c546b51ecf0b | 345 | |
XkLi | 0:c546b51ecf0b | 346 | if( BitDepth == 16 ) |
XkLi | 0:c546b51ecf0b | 347 | { |
XkLi | 0:c546b51ecf0b | 348 | int DataBytes = Width*2; |
XkLi | 0:c546b51ecf0b | 349 | int PaddingBytes = ( 4 - DataBytes % 4 ) % 4; |
XkLi | 0:c546b51ecf0b | 350 | |
XkLi | 0:c546b51ecf0b | 351 | // set the default mask |
XkLi | 0:c546b51ecf0b | 352 | |
XkLi | 0:c546b51ecf0b | 353 | ebmpWORD BlueMask = 31; // bits 12-16 |
XkLi | 0:c546b51ecf0b | 354 | ebmpWORD GreenMask = 992; // bits 7-11 |
XkLi | 0:c546b51ecf0b | 355 | ebmpWORD RedMask = 31744; // bits 2-6 |
XkLi | 0:c546b51ecf0b | 356 | |
XkLi | 0:c546b51ecf0b | 357 | // read the bit fields, if necessary, to |
XkLi | 0:c546b51ecf0b | 358 | // override the default 5-5-5 mask |
XkLi | 0:c546b51ecf0b | 359 | |
XkLi | 0:c546b51ecf0b | 360 | if( bmih.biCompression != 0 ) |
XkLi | 0:c546b51ecf0b | 361 | { |
XkLi | 0:c546b51ecf0b | 362 | // read the three bit masks |
XkLi | 0:c546b51ecf0b | 363 | |
XkLi | 0:c546b51ecf0b | 364 | ebmpWORD TempMaskWORD; |
XkLi | 0:c546b51ecf0b | 365 | |
XkLi | 0:c546b51ecf0b | 366 | SafeFread( (char*) &RedMask , 2 , 1 , fp ); |
XkLi | 0:c546b51ecf0b | 367 | SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); |
XkLi | 0:c546b51ecf0b | 368 | |
XkLi | 0:c546b51ecf0b | 369 | SafeFread( (char*) &GreenMask , 2 , 1 , fp ); |
XkLi | 0:c546b51ecf0b | 370 | SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); |
XkLi | 0:c546b51ecf0b | 371 | |
XkLi | 0:c546b51ecf0b | 372 | SafeFread( (char*) &BlueMask , 2 , 1 , fp ); |
XkLi | 0:c546b51ecf0b | 373 | SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); |
XkLi | 0:c546b51ecf0b | 374 | } |
XkLi | 0:c546b51ecf0b | 375 | |
XkLi | 0:c546b51ecf0b | 376 | // read and skip any meta data |
XkLi | 0:c546b51ecf0b | 377 | |
XkLi | 0:c546b51ecf0b | 378 | if( BytesToSkip > 0 ) |
XkLi | 0:c546b51ecf0b | 379 | { |
XkLi | 0:c546b51ecf0b | 380 | ebmpBYTE* TempSkipBYTE; |
XkLi | 0:c546b51ecf0b | 381 | TempSkipBYTE = new ebmpBYTE [BytesToSkip]; |
XkLi | 0:c546b51ecf0b | 382 | SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); |
XkLi | 0:c546b51ecf0b | 383 | delete [] TempSkipBYTE; |
XkLi | 0:c546b51ecf0b | 384 | } |
XkLi | 0:c546b51ecf0b | 385 | |
XkLi | 0:c546b51ecf0b | 386 | // determine the red, green and blue shifts |
XkLi | 0:c546b51ecf0b | 387 | |
XkLi | 0:c546b51ecf0b | 388 | int GreenShift = 0; |
XkLi | 0:c546b51ecf0b | 389 | ebmpWORD TempShiftWORD = GreenMask; |
XkLi | 0:c546b51ecf0b | 390 | while( TempShiftWORD > 31 ) |
XkLi | 0:c546b51ecf0b | 391 | { TempShiftWORD = TempShiftWORD>>1; GreenShift++; } |
XkLi | 0:c546b51ecf0b | 392 | int BlueShift = 0; |
XkLi | 0:c546b51ecf0b | 393 | TempShiftWORD = BlueMask; |
XkLi | 0:c546b51ecf0b | 394 | while( TempShiftWORD > 31 ) |
XkLi | 0:c546b51ecf0b | 395 | { TempShiftWORD = TempShiftWORD>>1; BlueShift++; } |
XkLi | 0:c546b51ecf0b | 396 | int RedShift = 0; |
XkLi | 0:c546b51ecf0b | 397 | TempShiftWORD = RedMask; |
XkLi | 0:c546b51ecf0b | 398 | while( TempShiftWORD > 31 ) |
XkLi | 0:c546b51ecf0b | 399 | { TempShiftWORD = TempShiftWORD>>1; RedShift++; } |
XkLi | 0:c546b51ecf0b | 400 | |
XkLi | 0:c546b51ecf0b | 401 | // read the actual pixels |
XkLi | 0:c546b51ecf0b | 402 | |
XkLi | 0:c546b51ecf0b | 403 | for( j=Height-1 ; j >= 0 ; j-- ) |
XkLi | 0:c546b51ecf0b | 404 | { |
XkLi | 0:c546b51ecf0b | 405 | i=0; |
XkLi | 0:c546b51ecf0b | 406 | int ReadNumber = 0; |
XkLi | 0:c546b51ecf0b | 407 | while( ReadNumber < DataBytes ) |
XkLi | 0:c546b51ecf0b | 408 | { |
XkLi | 0:c546b51ecf0b | 409 | ebmpWORD TempWORD; |
XkLi | 0:c546b51ecf0b | 410 | SafeFread( (char*) &TempWORD , 2 , 1 , fp ); |
XkLi | 0:c546b51ecf0b | 411 | ReadNumber += 2; |
XkLi | 0:c546b51ecf0b | 412 | |
XkLi | 0:c546b51ecf0b | 413 | ebmpWORD Red = RedMask & TempWORD; |
XkLi | 0:c546b51ecf0b | 414 | ebmpWORD Green = GreenMask & TempWORD; |
XkLi | 0:c546b51ecf0b | 415 | ebmpWORD Blue = BlueMask & TempWORD; |
XkLi | 0:c546b51ecf0b | 416 | |
XkLi | 0:c546b51ecf0b | 417 | ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift); |
XkLi | 0:c546b51ecf0b | 418 | ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift); |
XkLi | 0:c546b51ecf0b | 419 | ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift); |
XkLi | 0:c546b51ecf0b | 420 | |
XkLi | 0:c546b51ecf0b | 421 | int color = 0x00000000 | (RedBYTE << 16) | (GreenBYTE << 8) | (BlueBYTE); |
XkLi | 0:c546b51ecf0b | 422 | (*lcd).pixel((130-Width)/2+i,(130-Height)/2+j,color); |
XkLi | 0:c546b51ecf0b | 423 | i++; |
XkLi | 0:c546b51ecf0b | 424 | } |
XkLi | 0:c546b51ecf0b | 425 | ReadNumber = 0; |
XkLi | 0:c546b51ecf0b | 426 | while( ReadNumber < PaddingBytes ) |
XkLi | 0:c546b51ecf0b | 427 | { |
XkLi | 0:c546b51ecf0b | 428 | ebmpBYTE TempBYTE; |
XkLi | 0:c546b51ecf0b | 429 | SafeFread( (char*) &TempBYTE , 1, 1, fp); |
XkLi | 0:c546b51ecf0b | 430 | ReadNumber++; |
XkLi | 0:c546b51ecf0b | 431 | } |
XkLi | 0:c546b51ecf0b | 432 | } |
XkLi | 0:c546b51ecf0b | 433 | |
XkLi | 0:c546b51ecf0b | 434 | } |
XkLi | 0:c546b51ecf0b | 435 | |
XkLi | 0:c546b51ecf0b | 436 | fclose(fp); |
XkLi | 0:c546b51ecf0b | 437 | return true; |
XkLi | 0:c546b51ecf0b | 438 | } |
XkLi | 0:c546b51ecf0b | 439 | |
XkLi | 0:c546b51ecf0b | 440 | |
XkLi | 0:c546b51ecf0b | 441 | BMIH::BMIH() |
XkLi | 0:c546b51ecf0b | 442 | { |
XkLi | 0:c546b51ecf0b | 443 | biPlanes = 1; |
XkLi | 0:c546b51ecf0b | 444 | biCompression = 0; |
XkLi | 0:c546b51ecf0b | 445 | biXPelsPerMeter = DefaultXPelsPerMeter; |
XkLi | 0:c546b51ecf0b | 446 | biYPelsPerMeter = DefaultYPelsPerMeter; |
XkLi | 0:c546b51ecf0b | 447 | biClrUsed = 0; |
XkLi | 0:c546b51ecf0b | 448 | biClrImportant = 0; |
XkLi | 0:c546b51ecf0b | 449 | } |
XkLi | 0:c546b51ecf0b | 450 | |
XkLi | 0:c546b51ecf0b | 451 | BMFH::BMFH() |
XkLi | 0:c546b51ecf0b | 452 | { |
XkLi | 0:c546b51ecf0b | 453 | bfType = 19778; |
XkLi | 0:c546b51ecf0b | 454 | bfReserved1 = 0; |
XkLi | 0:c546b51ecf0b | 455 | bfReserved2 = 0; |
XkLi | 0:c546b51ecf0b | 456 | } |