Richard Parker / EALCD
Committer:
richardparker
Date:
Thu Mar 04 10:54:06 2010 +0000
Revision:
1:f04bcaea1d60
Parent:
0:839ecbf5cb2a
Child:
3:24fbf4dbd7e5

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
richardparker 0:839ecbf5cb2a 1 // Copyright 2010 Richard Parker
richardparker 0:839ecbf5cb2a 2
richardparker 0:839ecbf5cb2a 3 #include "mbed.h"
richardparker 0:839ecbf5cb2a 4
richardparker 0:839ecbf5cb2a 5 #include "EAImage.h"
richardparker 0:839ecbf5cb2a 6
richardparker 0:839ecbf5cb2a 7 #include "../graphics/EAPen.h"
richardparker 0:839ecbf5cb2a 8 #include "../graphics/EAColor.h"
richardparker 0:839ecbf5cb2a 9 #include "../screen/EALCD.h"
richardparker 0:839ecbf5cb2a 10
richardparker 0:839ecbf5cb2a 11 EAImage::EAImage()
richardparker 0:839ecbf5cb2a 12 : _path(NULL),
richardparker 1:f04bcaea1d60 13 _palette(NULL),
richardparker 1:f04bcaea1d60 14 _dataOffset(0),
richardparker 1:f04bcaea1d60 15 _mask(false)
richardparker 0:839ecbf5cb2a 16 {
richardparker 1:f04bcaea1d60 17 // Start from known state.
richardparker 1:f04bcaea1d60 18 unload();
richardparker 0:839ecbf5cb2a 19 }
richardparker 0:839ecbf5cb2a 20
richardparker 0:839ecbf5cb2a 21 EAImage::~EAImage()
richardparker 0:839ecbf5cb2a 22 {
richardparker 0:839ecbf5cb2a 23 }
richardparker 0:839ecbf5cb2a 24
richardparker 1:f04bcaea1d60 25 bool EAImage::_loadPalette(FILE* fp)
richardparker 1:f04bcaea1d60 26 {
richardparker 1:f04bcaea1d60 27 // Can't do anything with a null pointer.
richardparker 1:f04bcaea1d60 28 if (fp == NULL)
richardparker 1:f04bcaea1d60 29 {
richardparker 1:f04bcaea1d60 30 return false;
richardparker 1:f04bcaea1d60 31 }
richardparker 1:f04bcaea1d60 32
richardparker 1:f04bcaea1d60 33 // Clear any previously loaded palette.
richardparker 1:f04bcaea1d60 34 if (_palette != NULL)
richardparker 1:f04bcaea1d60 35 {
richardparker 1:f04bcaea1d60 36 delete[] _palette;
richardparker 1:f04bcaea1d60 37 _palette = NULL;
richardparker 1:f04bcaea1d60 38 }
richardparker 1:f04bcaea1d60 39
richardparker 1:f04bcaea1d60 40 // If the number of bits is not less than 16 then return after having cleared the
richardparker 1:f04bcaea1d60 41 // palette. There is no palette required.
richardparker 1:f04bcaea1d60 42 if (info().bitsPerPixel >= 16)
richardparker 1:f04bcaea1d60 43 {
richardparker 1:f04bcaea1d60 44 return true;
richardparker 1:f04bcaea1d60 45 }
richardparker 1:f04bcaea1d60 46
richardparker 1:f04bcaea1d60 47 // First create a palette of the required size.
richardparker 1:f04bcaea1d60 48 unsigned int noColors = info().noColors;
richardparker 1:f04bcaea1d60 49
richardparker 1:f04bcaea1d60 50 // When 0 the number of colors is equal to 2^n where n is the bits per pixel.
richardparker 1:f04bcaea1d60 51 if (noColors == 0)
richardparker 1:f04bcaea1d60 52 {
richardparker 1:f04bcaea1d60 53 noColors = pow((double)2, info().bitsPerPixel);
richardparker 1:f04bcaea1d60 54 }
richardparker 1:f04bcaea1d60 55
richardparker 1:f04bcaea1d60 56 // Create the palette and assign the memory.
richardparker 1:f04bcaea1d60 57 _palette = new EAColor[noColors];
richardparker 1:f04bcaea1d60 58
richardparker 1:f04bcaea1d60 59 // Now parse the palette. First seek to the start of the palette. This must be the
richardparker 1:f04bcaea1d60 60 // start of the bitmap data minus the number of colour entries multiplied by 4 (the
richardparker 1:f04bcaea1d60 61 // colours are stored as 4 byte long entries, the last byte can be ignored).
richardparker 1:f04bcaea1d60 62 unsigned int offset = _dataOffset - (noColors*4);
richardparker 1:f04bcaea1d60 63
richardparker 1:f04bcaea1d60 64 // Seek to the start of the table.
richardparker 1:f04bcaea1d60 65 fseek(fp, offset, SEEK_SET);
richardparker 1:f04bcaea1d60 66 unsigned char buffer[4];
richardparker 1:f04bcaea1d60 67
richardparker 1:f04bcaea1d60 68 // Iterate through the table filling the palette as needed.
richardparker 1:f04bcaea1d60 69 for (int i = 0; i < noColors; i++)
richardparker 1:f04bcaea1d60 70 {
richardparker 1:f04bcaea1d60 71 int sizeRead = fread(&buffer, 4, 1, fp);
richardparker 1:f04bcaea1d60 72
richardparker 1:f04bcaea1d60 73 if (sizeRead == 1)
richardparker 1:f04bcaea1d60 74 {
richardparker 1:f04bcaea1d60 75 _palette[i].setRgb(buffer[2], buffer[1], buffer[0]);
richardparker 1:f04bcaea1d60 76 }
richardparker 1:f04bcaea1d60 77 }
richardparker 1:f04bcaea1d60 78
richardparker 1:f04bcaea1d60 79 return true;
richardparker 1:f04bcaea1d60 80 }
richardparker 1:f04bcaea1d60 81
richardparker 0:839ecbf5cb2a 82 bool EAImage::_loadHeader(const char* path)
richardparker 0:839ecbf5cb2a 83 {
richardparker 0:839ecbf5cb2a 84 if (path == NULL)
richardparker 0:839ecbf5cb2a 85 {
richardparker 0:839ecbf5cb2a 86 // Invalid path passed in.
richardparker 0:839ecbf5cb2a 87 return false;
richardparker 0:839ecbf5cb2a 88 }
richardparker 0:839ecbf5cb2a 89
richardparker 0:839ecbf5cb2a 90 // Try and open the file, check type and load width and height.
richardparker 0:839ecbf5cb2a 91 FILE* fp = fopen(path, "r");
richardparker 0:839ecbf5cb2a 92 if (fp == NULL)
richardparker 0:839ecbf5cb2a 93 {
richardparker 0:839ecbf5cb2a 94 return false;
richardparker 0:839ecbf5cb2a 95 }
richardparker 0:839ecbf5cb2a 96
richardparker 0:839ecbf5cb2a 97 unsigned int bufint = 0;
richardparker 0:839ecbf5cb2a 98 unsigned int offset = 0;
richardparker 0:839ecbf5cb2a 99
richardparker 0:839ecbf5cb2a 100 // Read the magic numbers at start.
richardparker 0:839ecbf5cb2a 101 fread(&bufint, 1, 2, fp);
richardparker 0:839ecbf5cb2a 102 if (bufint != 0x4d42)
richardparker 0:839ecbf5cb2a 103 {
richardparker 0:839ecbf5cb2a 104 // Clean up file handle.
richardparker 0:839ecbf5cb2a 105 fclose(fp);
richardparker 0:839ecbf5cb2a 106
richardparker 0:839ecbf5cb2a 107 // Header incorrect.
richardparker 0:839ecbf5cb2a 108 return false;
richardparker 0:839ecbf5cb2a 109 }
richardparker 0:839ecbf5cb2a 110
richardparker 0:839ecbf5cb2a 111 // Now read the bmp file size.
richardparker 0:839ecbf5cb2a 112 fread(&bufint, 1, 4, fp);
richardparker 0:839ecbf5cb2a 113
richardparker 0:839ecbf5cb2a 114 // Now read the two creator values and throw away.
richardparker 0:839ecbf5cb2a 115 fread(&bufint, 1, 2, fp);
richardparker 0:839ecbf5cb2a 116 fread(&bufint, 1, 2, fp);
richardparker 0:839ecbf5cb2a 117
richardparker 0:839ecbf5cb2a 118 // Now read the offset for the bitmap data.
richardparker 0:839ecbf5cb2a 119 fread(&bufint, 1, 4, fp);
richardparker 0:839ecbf5cb2a 120 offset = bufint;
richardparker 0:839ecbf5cb2a 121
richardparker 0:839ecbf5cb2a 122 // Retrieve the header.
richardparker 1:f04bcaea1d60 123 fread(&_header, sizeof(EABMPHeader), 1, fp);
richardparker 0:839ecbf5cb2a 124
richardparker 1:f04bcaea1d60 125 // Make sure the compression type is a value that can be dealt with.
richardparker 1:f04bcaea1d60 126 if ((info().compressionType != 3) && (info().compressionType != 0))
richardparker 1:f04bcaea1d60 127 {
richardparker 0:839ecbf5cb2a 128 // Clean up file handle.
richardparker 0:839ecbf5cb2a 129 fclose(fp);
richardparker 0:839ecbf5cb2a 130
richardparker 0:839ecbf5cb2a 131 // Header incorrect.
richardparker 0:839ecbf5cb2a 132 return false;
richardparker 0:839ecbf5cb2a 133 }
richardparker 0:839ecbf5cb2a 134
richardparker 0:839ecbf5cb2a 135 // Set the values for later.
richardparker 0:839ecbf5cb2a 136 _dataOffset = offset;
richardparker 1:f04bcaea1d60 137 setWidth(info().width);
richardparker 1:f04bcaea1d60 138 setHeight(info().height);
richardparker 1:f04bcaea1d60 139
richardparker 0:839ecbf5cb2a 140 // Close the file.
richardparker 0:839ecbf5cb2a 141 fclose(fp);
richardparker 0:839ecbf5cb2a 142
richardparker 0:839ecbf5cb2a 143 return true;
richardparker 0:839ecbf5cb2a 144 }
richardparker 0:839ecbf5cb2a 145
richardparker 1:f04bcaea1d60 146 int EAImage::_wordsInRow()
richardparker 1:f04bcaea1d60 147 {
richardparker 1:f04bcaea1d60 148 // If there were no padding to 32 bit boundaries this would be the number of bits per row
richardparker 1:f04bcaea1d60 149 // in the file.
richardparker 1:f04bcaea1d60 150 int bitsPerWidth = width() * info().bitsPerPixel;
richardparker 1:f04bcaea1d60 151
richardparker 1:f04bcaea1d60 152 // This is the row size with padding on the end.
richardparker 1:f04bcaea1d60 153 int remainder = (bitsPerWidth % 32);
richardparker 1:f04bcaea1d60 154 int bitsPerRow = (remainder == 0) ? bitsPerWidth : bitsPerWidth + (32 - remainder);
richardparker 1:f04bcaea1d60 155
richardparker 1:f04bcaea1d60 156 // Return the size in number of words.
richardparker 1:f04bcaea1d60 157 return (bitsPerRow / 32);
richardparker 1:f04bcaea1d60 158 }
richardparker 1:f04bcaea1d60 159
richardparker 1:f04bcaea1d60 160 int EAImage::_wordForX(unsigned int x)
richardparker 1:f04bcaea1d60 161 {
richardparker 1:f04bcaea1d60 162 int bitForX = x * info().bitsPerPixel;
richardparker 1:f04bcaea1d60 163
richardparker 1:f04bcaea1d60 164 return (bitForX / 32);
richardparker 1:f04bcaea1d60 165 }
richardparker 1:f04bcaea1d60 166
richardparker 1:f04bcaea1d60 167 int EAImage::_xWordOffset(unsigned int x)
richardparker 1:f04bcaea1d60 168 {
richardparker 1:f04bcaea1d60 169 int bitForX = x * info().bitsPerPixel;
richardparker 1:f04bcaea1d60 170
richardparker 1:f04bcaea1d60 171 return (bitForX % 32);
richardparker 1:f04bcaea1d60 172 }
richardparker 1:f04bcaea1d60 173
richardparker 1:f04bcaea1d60 174 unsigned short EAImage::_getColourAtOffset(unsigned int word, int offset)
richardparker 1:f04bcaea1d60 175 {
richardparker 1:f04bcaea1d60 176 // Sort bytes for endianness.
richardparker 1:f04bcaea1d60 177 unsigned char* cptr;
richardparker 1:f04bcaea1d60 178 unsigned short result = 0x0000;
richardparker 1:f04bcaea1d60 179
richardparker 1:f04bcaea1d60 180 // Now need to decide how to cast the value to a colour.
richardparker 1:f04bcaea1d60 181 switch (info().bitsPerPixel)
richardparker 1:f04bcaea1d60 182 {
richardparker 1:f04bcaea1d60 183 // Swap the bytes around.
richardparker 1:f04bcaea1d60 184 case 32:
richardparker 1:f04bcaea1d60 185 case 4:
richardparker 1:f04bcaea1d60 186 case 8:
richardparker 1:f04bcaea1d60 187 case 1:
richardparker 1:f04bcaea1d60 188 unsigned char tmp;
richardparker 1:f04bcaea1d60 189 cptr = (unsigned char*)&word;
richardparker 1:f04bcaea1d60 190 tmp = cptr[0];
richardparker 1:f04bcaea1d60 191 cptr[0] = cptr[3];
richardparker 1:f04bcaea1d60 192 cptr[3] = tmp;
richardparker 1:f04bcaea1d60 193 tmp = cptr[1];
richardparker 1:f04bcaea1d60 194 cptr[1] = cptr[2];
richardparker 1:f04bcaea1d60 195 cptr[2] = tmp;
richardparker 1:f04bcaea1d60 196 break;
richardparker 1:f04bcaea1d60 197
richardparker 1:f04bcaea1d60 198 default:
richardparker 1:f04bcaea1d60 199 // Swap the 16bits around.
richardparker 1:f04bcaea1d60 200 case 16:
richardparker 1:f04bcaea1d60 201 unsigned char tmpa;
richardparker 1:f04bcaea1d60 202 unsigned char tmpb;
richardparker 1:f04bcaea1d60 203 cptr = (unsigned char*)&word;
richardparker 1:f04bcaea1d60 204 tmpa = cptr[1];
richardparker 1:f04bcaea1d60 205 tmpb = cptr[0];
richardparker 1:f04bcaea1d60 206 cptr[1] = cptr[3];
richardparker 1:f04bcaea1d60 207 cptr[0] = cptr[2];
richardparker 1:f04bcaea1d60 208 cptr[3] = tmpa;
richardparker 1:f04bcaea1d60 209 cptr[2] = tmpb;
richardparker 1:f04bcaea1d60 210 break;
richardparker 1:f04bcaea1d60 211 }
richardparker 1:f04bcaea1d60 212
richardparker 1:f04bcaea1d60 213 // First shift off the pixels above.
richardparker 1:f04bcaea1d60 214 word = word << offset;
richardparker 1:f04bcaea1d60 215
richardparker 1:f04bcaea1d60 216 // Now shift down so that pixel is in lsb.
richardparker 1:f04bcaea1d60 217 word = word >> (32 - info().bitsPerPixel);
richardparker 1:f04bcaea1d60 218
richardparker 1:f04bcaea1d60 219 EAColor c;
richardparker 1:f04bcaea1d60 220
richardparker 1:f04bcaea1d60 221 // Now need to decide how to cast the value to a colour.
richardparker 1:f04bcaea1d60 222 switch (info().bitsPerPixel)
richardparker 1:f04bcaea1d60 223 {
richardparker 1:f04bcaea1d60 224 case 8:
richardparker 1:f04bcaea1d60 225 case 4:
richardparker 1:f04bcaea1d60 226 case 1:
richardparker 1:f04bcaea1d60 227 if (_palette != NULL)
richardparker 1:f04bcaea1d60 228 {
richardparker 1:f04bcaea1d60 229 result = _palette[word].rawValue();
richardparker 1:f04bcaea1d60 230 } else {
richardparker 1:f04bcaea1d60 231 result = 0x0000;
richardparker 1:f04bcaea1d60 232 }
richardparker 1:f04bcaea1d60 233 break;
richardparker 1:f04bcaea1d60 234
richardparker 1:f04bcaea1d60 235 // By default just cast to unsigned short and return.
richardparker 1:f04bcaea1d60 236 default:
richardparker 1:f04bcaea1d60 237 case 16:
richardparker 1:f04bcaea1d60 238 result = (unsigned short)(word);
richardparker 1:f04bcaea1d60 239 break;
richardparker 1:f04bcaea1d60 240
richardparker 1:f04bcaea1d60 241 case 24:
richardparker 1:f04bcaea1d60 242 case 32:
richardparker 1:f04bcaea1d60 243 unsigned char b = ((word << 0) >> 24);
richardparker 1:f04bcaea1d60 244 unsigned char g = ((word << 8) >> 24);
richardparker 1:f04bcaea1d60 245 unsigned char r = ((word << 16) >> 24);
richardparker 1:f04bcaea1d60 246
richardparker 1:f04bcaea1d60 247 c.setRgb(r, g, b);
richardparker 1:f04bcaea1d60 248 result = c.rawValue();
richardparker 1:f04bcaea1d60 249 break;
richardparker 1:f04bcaea1d60 250 }
richardparker 1:f04bcaea1d60 251
richardparker 1:f04bcaea1d60 252 return result;
richardparker 1:f04bcaea1d60 253 }
richardparker 1:f04bcaea1d60 254
richardparker 0:839ecbf5cb2a 255 bool EAImage::load(const char* path)
richardparker 0:839ecbf5cb2a 256 {
richardparker 0:839ecbf5cb2a 257 if (path == NULL)
richardparker 0:839ecbf5cb2a 258 {
richardparker 1:f04bcaea1d60 259 // Reset all of the state.
richardparker 1:f04bcaea1d60 260 unload();
richardparker 1:f04bcaea1d60 261
richardparker 0:839ecbf5cb2a 262 // Invalid path passed in.
richardparker 0:839ecbf5cb2a 263 return false;
richardparker 0:839ecbf5cb2a 264 }
richardparker 0:839ecbf5cb2a 265
richardparker 0:839ecbf5cb2a 266 if (_loadHeader(path) == false)
richardparker 0:839ecbf5cb2a 267 {
richardparker 1:f04bcaea1d60 268 // Reset all of the state.
richardparker 1:f04bcaea1d60 269 unload();
richardparker 1:f04bcaea1d60 270
richardparker 0:839ecbf5cb2a 271 return false;
richardparker 0:839ecbf5cb2a 272 }
richardparker 0:839ecbf5cb2a 273
richardparker 0:839ecbf5cb2a 274 int pathLen = strlen(path);
richardparker 0:839ecbf5cb2a 275
richardparker 0:839ecbf5cb2a 276 // If already loaded an image then clear to load the new one.
richardparker 0:839ecbf5cb2a 277 if (_path != NULL)
richardparker 0:839ecbf5cb2a 278 {
richardparker 0:839ecbf5cb2a 279 delete[] _path;
richardparker 0:839ecbf5cb2a 280 _path = NULL;
richardparker 0:839ecbf5cb2a 281 }
richardparker 0:839ecbf5cb2a 282
richardparker 0:839ecbf5cb2a 283 // Now allocate enough space to hold path. Note +1 for null character.
richardparker 0:839ecbf5cb2a 284 _path = new char[pathLen+1];
richardparker 0:839ecbf5cb2a 285
richardparker 0:839ecbf5cb2a 286 // Now copy over passed in path to path variable.
richardparker 0:839ecbf5cb2a 287 strcpy(_path, path);
richardparker 0:839ecbf5cb2a 288
richardparker 0:839ecbf5cb2a 289 // Image loaded successfully.
richardparker 0:839ecbf5cb2a 290 return true;
richardparker 0:839ecbf5cb2a 291 }
richardparker 0:839ecbf5cb2a 292
richardparker 1:f04bcaea1d60 293 void EAImage::unload()
richardparker 1:f04bcaea1d60 294 {
richardparker 1:f04bcaea1d60 295 // Empty the header struct.
richardparker 1:f04bcaea1d60 296 _header.headerSize = 0;
richardparker 1:f04bcaea1d60 297 _header.width = 0;
richardparker 1:f04bcaea1d60 298 _header.height = 0;
richardparker 1:f04bcaea1d60 299 _header.noColorPlanes = 0;
richardparker 1:f04bcaea1d60 300 _header.bitsPerPixel = 0;
richardparker 1:f04bcaea1d60 301 _header.compressionType = 0;
richardparker 1:f04bcaea1d60 302 _header.bmpSize = 0;
richardparker 1:f04bcaea1d60 303 _header.horizontalRes = 0;
richardparker 1:f04bcaea1d60 304 _header.verticalRes = 0;
richardparker 1:f04bcaea1d60 305 _header.noColors = 0;
richardparker 1:f04bcaea1d60 306 _header.noImportantColors = 0;
richardparker 1:f04bcaea1d60 307
richardparker 1:f04bcaea1d60 308 // Clear the path.
richardparker 1:f04bcaea1d60 309 if (_path != NULL)
richardparker 1:f04bcaea1d60 310 {
richardparker 1:f04bcaea1d60 311 delete[] _path;
richardparker 1:f04bcaea1d60 312 _path = NULL;
richardparker 1:f04bcaea1d60 313 }
richardparker 1:f04bcaea1d60 314
richardparker 1:f04bcaea1d60 315 // Clear the palette.
richardparker 1:f04bcaea1d60 316 if (_palette != NULL)
richardparker 1:f04bcaea1d60 317 {
richardparker 1:f04bcaea1d60 318 delete[] _palette;
richardparker 1:f04bcaea1d60 319 _palette = NULL;
richardparker 1:f04bcaea1d60 320 }
richardparker 1:f04bcaea1d60 321
richardparker 1:f04bcaea1d60 322 // Clear the data offset.
richardparker 1:f04bcaea1d60 323 _dataOffset = 0;
richardparker 1:f04bcaea1d60 324
richardparker 1:f04bcaea1d60 325 // Set the size to 0.
richardparker 1:f04bcaea1d60 326 setWidth(0);
richardparker 1:f04bcaea1d60 327 setHeight(0);
richardparker 1:f04bcaea1d60 328
richardparker 1:f04bcaea1d60 329 // Set as not a mask.
richardparker 1:f04bcaea1d60 330 _mask = false;
richardparker 1:f04bcaea1d60 331 }
richardparker 1:f04bcaea1d60 332
richardparker 0:839ecbf5cb2a 333 void EAImage::paint(EALCD& lcd)
richardparker 0:839ecbf5cb2a 334 {
richardparker 0:839ecbf5cb2a 335 paint(lcd, 0, 0, width(), height());
richardparker 0:839ecbf5cb2a 336 }
richardparker 0:839ecbf5cb2a 337
richardparker 0:839ecbf5cb2a 338 void EAImage::paint(EALCD& lcd, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
richardparker 0:839ecbf5cb2a 339 {
richardparker 0:839ecbf5cb2a 340 if (isValid() == false)
richardparker 0:839ecbf5cb2a 341 {
richardparker 0:839ecbf5cb2a 342 return;
richardparker 0:839ecbf5cb2a 343 }
richardparker 0:839ecbf5cb2a 344
richardparker 0:839ecbf5cb2a 345 // Don't allow draw out of range.
richardparker 0:839ecbf5cb2a 346 if (x + w > width())
richardparker 0:839ecbf5cb2a 347 {
richardparker 0:839ecbf5cb2a 348 return;
richardparker 0:839ecbf5cb2a 349 }
richardparker 0:839ecbf5cb2a 350
richardparker 0:839ecbf5cb2a 351 if (y + h > height())
richardparker 0:839ecbf5cb2a 352 {
richardparker 0:839ecbf5cb2a 353 return;
richardparker 0:839ecbf5cb2a 354 }
richardparker 0:839ecbf5cb2a 355
richardparker 1:f04bcaea1d60 356 // Buffer to hold load one line at a time this must be large enough to hold all of the data used
richardparker 1:f04bcaea1d60 357 // for a line in the file. Note that the line in the file is padded so that it always ends on a
richardparker 1:f04bcaea1d60 358 // 32 bit boundary.
richardparker 1:f04bcaea1d60 359 int wordsInRow = _wordsInRow();
richardparker 1:f04bcaea1d60 360 unsigned int buffer[wordsInRow];
richardparker 0:839ecbf5cb2a 361 int xD = 0;
richardparker 0:839ecbf5cb2a 362 int yD = 0;
richardparker 1:f04bcaea1d60 363 int wordOffset = 0;
richardparker 1:f04bcaea1d60 364 int bitsPerPixel = info().bitsPerPixel;
richardparker 1:f04bcaea1d60 365 unsigned short data = 0;
richardparker 0:839ecbf5cb2a 366
richardparker 0:839ecbf5cb2a 367 // Try and open the file, skip straight to the data.
richardparker 0:839ecbf5cb2a 368 FILE* fp = fopen(_path, "r");
richardparker 0:839ecbf5cb2a 369 if (fp == NULL)
richardparker 0:839ecbf5cb2a 370 {
richardparker 0:839ecbf5cb2a 371 return;
richardparker 0:839ecbf5cb2a 372 }
richardparker 0:839ecbf5cb2a 373
richardparker 1:f04bcaea1d60 374 // If the bits per pixel are less than 16 then the bitmap is using a colour
richardparker 1:f04bcaea1d60 375 // palette which should be loaded first.
richardparker 1:f04bcaea1d60 376 _loadPalette(fp);
richardparker 1:f04bcaea1d60 377
richardparker 0:839ecbf5cb2a 378 // Skip the header and size.
richardparker 0:839ecbf5cb2a 379 fseek(fp, _dataOffset, SEEK_SET);
richardparker 0:839ecbf5cb2a 380
richardparker 0:839ecbf5cb2a 381 // Prepare the lcd for drawing.
richardparker 0:839ecbf5cb2a 382 lcd._window(this->x(), this->y(), w, h);
richardparker 0:839ecbf5cb2a 383 lcd._moveTo(this->x(), this->y());
richardparker 0:839ecbf5cb2a 384
richardparker 0:839ecbf5cb2a 385 // Move in the file to the first pixel in the window.
richardparker 1:f04bcaea1d60 386 fseek(fp, (y*wordsInRow*4)+(_wordForX(x)*4), SEEK_CUR);
richardparker 1:f04bcaea1d60 387
richardparker 0:839ecbf5cb2a 388 // Now read the data.
richardparker 0:839ecbf5cb2a 389 while (!feof(fp))
richardparker 0:839ecbf5cb2a 390 {
richardparker 1:f04bcaea1d60 391 wordOffset = _xWordOffset(x);
richardparker 1:f04bcaea1d60 392
richardparker 1:f04bcaea1d60 393 int sizeRead = fread(&buffer, 4, wordsInRow, fp);
richardparker 0:839ecbf5cb2a 394
richardparker 0:839ecbf5cb2a 395 for (int i = 0; i < sizeRead; i++)
richardparker 1:f04bcaea1d60 396 {
richardparker 1:f04bcaea1d60 397 while (wordOffset < 32)
richardparker 1:f04bcaea1d60 398 {
richardparker 1:f04bcaea1d60 399 // Convert the colour to a 16 bit colour value that can be written directly to the screen.
richardparker 1:f04bcaea1d60 400 data = _getColourAtOffset(buffer[i], wordOffset);
richardparker 1:f04bcaea1d60 401
richardparker 1:f04bcaea1d60 402 if (isMask() == true)
richardparker 1:f04bcaea1d60 403 {
richardparker 1:f04bcaea1d60 404 // When a mask the 0x0000 value is transparent anything else is drawn with the pen color.
richardparker 1:f04bcaea1d60 405 if (data == 0x0000)
richardparker 1:f04bcaea1d60 406 {
richardparker 1:f04bcaea1d60 407 lcd.noop();
richardparker 1:f04bcaea1d60 408 } else {
richardparker 1:f04bcaea1d60 409 lcd._writeToDisplay(lcd.pen().color().rawValue());
richardparker 1:f04bcaea1d60 410 }
richardparker 1:f04bcaea1d60 411 } else {
richardparker 1:f04bcaea1d60 412 // Not a mask so just use colour that have loaded.
richardparker 1:f04bcaea1d60 413 lcd._writeToDisplay(data);
richardparker 1:f04bcaea1d60 414 }
richardparker 1:f04bcaea1d60 415
richardparker 1:f04bcaea1d60 416 // Got to next pixel in the word.
richardparker 1:f04bcaea1d60 417 wordOffset += bitsPerPixel;
richardparker 1:f04bcaea1d60 418
richardparker 1:f04bcaea1d60 419 // Keep count of current x value.
richardparker 1:f04bcaea1d60 420 xD++;
richardparker 1:f04bcaea1d60 421 if (xD == w)
richardparker 1:f04bcaea1d60 422 {
richardparker 1:f04bcaea1d60 423 break;
richardparker 1:f04bcaea1d60 424 }
richardparker 1:f04bcaea1d60 425 }
richardparker 1:f04bcaea1d60 426 wordOffset = 0;
richardparker 0:839ecbf5cb2a 427
richardparker 1:f04bcaea1d60 428 // When written all required pixels exit.
richardparker 0:839ecbf5cb2a 429 if (xD == w)
richardparker 0:839ecbf5cb2a 430 {
richardparker 0:839ecbf5cb2a 431 xD = 0;
richardparker 0:839ecbf5cb2a 432 break;
richardparker 0:839ecbf5cb2a 433 }
richardparker 0:839ecbf5cb2a 434 }
richardparker 0:839ecbf5cb2a 435
richardparker 0:839ecbf5cb2a 436 // Keep count of curernt y value.
richardparker 0:839ecbf5cb2a 437 yD++;
richardparker 0:839ecbf5cb2a 438 if (yD == h)
richardparker 0:839ecbf5cb2a 439 {
richardparker 0:839ecbf5cb2a 440 break;
richardparker 0:839ecbf5cb2a 441 }
richardparker 0:839ecbf5cb2a 442 }
richardparker 0:839ecbf5cb2a 443
richardparker 1:f04bcaea1d60 444 // Clear the palette.
richardparker 1:f04bcaea1d60 445 if (_palette != NULL)
richardparker 1:f04bcaea1d60 446 {
richardparker 1:f04bcaea1d60 447 delete[] _palette;
richardparker 1:f04bcaea1d60 448 _palette = NULL;
richardparker 1:f04bcaea1d60 449 }
richardparker 1:f04bcaea1d60 450
richardparker 0:839ecbf5cb2a 451 // Close the file and release handle.
richardparker 0:839ecbf5cb2a 452 fclose(fp);
richardparker 0:839ecbf5cb2a 453 }
richardparker 0:839ecbf5cb2a 454
richardparker 0:839ecbf5cb2a 455