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.
widgets/EAImage.cpp@6:4fe6f365cbeb, 2010-05-06 (annotated)
- Committer:
- richardparker
- Date:
- Thu May 06 23:32:14 2010 +0000
- Revision:
- 6:4fe6f365cbeb
- Parent:
- 3:24fbf4dbd7e5
Added caching for the fonts which seems to give ~20x improvement in rendering at the sacrifice of RAM.
Who changed what in which revision?
User | Revision | Line number | New 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 | 6:4fe6f365cbeb | 15 | _mask(false), |
richardparker | 6:4fe6f365cbeb | 16 | _cached(false), |
richardparker | 6:4fe6f365cbeb | 17 | _cache(NULL), |
richardparker | 6:4fe6f365cbeb | 18 | _size(0L), |
richardparker | 6:4fe6f365cbeb | 19 | _pos(0L) |
richardparker | 0:839ecbf5cb2a | 20 | { |
richardparker | 1:f04bcaea1d60 | 21 | // Start from known state. |
richardparker | 1:f04bcaea1d60 | 22 | unload(); |
richardparker | 0:839ecbf5cb2a | 23 | } |
richardparker | 0:839ecbf5cb2a | 24 | |
richardparker | 0:839ecbf5cb2a | 25 | EAImage::~EAImage() |
richardparker | 0:839ecbf5cb2a | 26 | { |
richardparker | 6:4fe6f365cbeb | 27 | unload(); |
richardparker | 6:4fe6f365cbeb | 28 | } |
richardparker | 6:4fe6f365cbeb | 29 | |
richardparker | 6:4fe6f365cbeb | 30 | int EAImage::_feof(FILE* stream) |
richardparker | 6:4fe6f365cbeb | 31 | { |
richardparker | 6:4fe6f365cbeb | 32 | if (isCached() == true) |
richardparker | 3:24fbf4dbd7e5 | 33 | { |
richardparker | 6:4fe6f365cbeb | 34 | return (_pos < _size) ? 0 : 1; |
richardparker | 6:4fe6f365cbeb | 35 | } else { |
richardparker | 6:4fe6f365cbeb | 36 | return feof(stream); |
richardparker | 6:4fe6f365cbeb | 37 | } |
richardparker | 6:4fe6f365cbeb | 38 | } |
richardparker | 6:4fe6f365cbeb | 39 | |
richardparker | 6:4fe6f365cbeb | 40 | |
richardparker | 6:4fe6f365cbeb | 41 | int EAImage::_fseek(FILE* stream, long int offset, int origin) |
richardparker | 6:4fe6f365cbeb | 42 | { |
richardparker | 6:4fe6f365cbeb | 43 | if (isCached() == true) |
richardparker | 6:4fe6f365cbeb | 44 | { |
richardparker | 6:4fe6f365cbeb | 45 | switch (origin) |
richardparker | 6:4fe6f365cbeb | 46 | { |
richardparker | 6:4fe6f365cbeb | 47 | default: |
richardparker | 6:4fe6f365cbeb | 48 | case SEEK_SET: |
richardparker | 6:4fe6f365cbeb | 49 | _pos = offset; |
richardparker | 6:4fe6f365cbeb | 50 | break; |
richardparker | 6:4fe6f365cbeb | 51 | case SEEK_CUR: |
richardparker | 6:4fe6f365cbeb | 52 | _pos = _pos + offset; |
richardparker | 6:4fe6f365cbeb | 53 | break; |
richardparker | 6:4fe6f365cbeb | 54 | case SEEK_END: |
richardparker | 6:4fe6f365cbeb | 55 | _pos = (_size-1) + offset; |
richardparker | 6:4fe6f365cbeb | 56 | break; |
richardparker | 6:4fe6f365cbeb | 57 | } |
richardparker | 6:4fe6f365cbeb | 58 | |
richardparker | 6:4fe6f365cbeb | 59 | // Make sure position within range. |
richardparker | 6:4fe6f365cbeb | 60 | if (_pos < 0) |
richardparker | 6:4fe6f365cbeb | 61 | { |
richardparker | 6:4fe6f365cbeb | 62 | _pos = 0; |
richardparker | 6:4fe6f365cbeb | 63 | return 0; |
richardparker | 6:4fe6f365cbeb | 64 | } |
richardparker | 6:4fe6f365cbeb | 65 | |
richardparker | 6:4fe6f365cbeb | 66 | if (_pos > (_size-1)) |
richardparker | 6:4fe6f365cbeb | 67 | { |
richardparker | 6:4fe6f365cbeb | 68 | _pos = (_size-1); |
richardparker | 6:4fe6f365cbeb | 69 | return 0; |
richardparker | 6:4fe6f365cbeb | 70 | } |
richardparker | 6:4fe6f365cbeb | 71 | |
richardparker | 6:4fe6f365cbeb | 72 | // Error. |
richardparker | 6:4fe6f365cbeb | 73 | return 1; |
richardparker | 6:4fe6f365cbeb | 74 | } else { |
richardparker | 6:4fe6f365cbeb | 75 | return fseek(stream, offset, origin); |
richardparker | 6:4fe6f365cbeb | 76 | } |
richardparker | 6:4fe6f365cbeb | 77 | } |
richardparker | 6:4fe6f365cbeb | 78 | |
richardparker | 6:4fe6f365cbeb | 79 | size_t EAImage::_fread(void* ptr, size_t size, size_t count, FILE* stream) |
richardparker | 6:4fe6f365cbeb | 80 | { |
richardparker | 6:4fe6f365cbeb | 81 | if (isCached() == true) |
richardparker | 6:4fe6f365cbeb | 82 | { |
richardparker | 6:4fe6f365cbeb | 83 | // Truncate size to fit array if needed. |
richardparker | 6:4fe6f365cbeb | 84 | if (_pos + (count*size) > _size) |
richardparker | 6:4fe6f365cbeb | 85 | { |
richardparker | 6:4fe6f365cbeb | 86 | count = (_size - _pos)/size; |
richardparker | 6:4fe6f365cbeb | 87 | } |
richardparker | 6:4fe6f365cbeb | 88 | |
richardparker | 6:4fe6f365cbeb | 89 | if (count <= 0) |
richardparker | 6:4fe6f365cbeb | 90 | { |
richardparker | 6:4fe6f365cbeb | 91 | return 0; |
richardparker | 6:4fe6f365cbeb | 92 | } |
richardparker | 6:4fe6f365cbeb | 93 | |
richardparker | 6:4fe6f365cbeb | 94 | // Now copy out of cache to array. |
richardparker | 6:4fe6f365cbeb | 95 | memcpy(ptr, &_cache[_pos], count*size); |
richardparker | 6:4fe6f365cbeb | 96 | |
richardparker | 6:4fe6f365cbeb | 97 | // Update the file position. |
richardparker | 6:4fe6f365cbeb | 98 | _pos = _pos + (count*size); |
richardparker | 6:4fe6f365cbeb | 99 | |
richardparker | 6:4fe6f365cbeb | 100 | // Return the number of bytes read. |
richardparker | 6:4fe6f365cbeb | 101 | return count; |
richardparker | 6:4fe6f365cbeb | 102 | } else { |
richardparker | 6:4fe6f365cbeb | 103 | return fread(ptr, size, count, stream); |
richardparker | 6:4fe6f365cbeb | 104 | } |
richardparker | 6:4fe6f365cbeb | 105 | } |
richardparker | 6:4fe6f365cbeb | 106 | |
richardparker | 6:4fe6f365cbeb | 107 | bool EAImage::_loadCache(FILE* fp) |
richardparker | 6:4fe6f365cbeb | 108 | { |
richardparker | 6:4fe6f365cbeb | 109 | // Can't do anything with a null pointer. |
richardparker | 6:4fe6f365cbeb | 110 | if (fp == NULL) |
richardparker | 6:4fe6f365cbeb | 111 | { |
richardparker | 6:4fe6f365cbeb | 112 | return false; |
richardparker | 3:24fbf4dbd7e5 | 113 | } |
richardparker | 3:24fbf4dbd7e5 | 114 | |
richardparker | 6:4fe6f365cbeb | 115 | // Clear any previously loaded cache. |
richardparker | 6:4fe6f365cbeb | 116 | if (_cache != NULL) |
richardparker | 6:4fe6f365cbeb | 117 | { |
richardparker | 6:4fe6f365cbeb | 118 | delete[] _cache; |
richardparker | 6:4fe6f365cbeb | 119 | _cache = NULL; |
richardparker | 6:4fe6f365cbeb | 120 | } |
richardparker | 6:4fe6f365cbeb | 121 | _size = 0L; |
richardparker | 6:4fe6f365cbeb | 122 | _pos = 0L; |
richardparker | 6:4fe6f365cbeb | 123 | |
richardparker | 6:4fe6f365cbeb | 124 | if (isCached() == false) |
richardparker | 6:4fe6f365cbeb | 125 | { |
richardparker | 6:4fe6f365cbeb | 126 | return true; |
richardparker | 6:4fe6f365cbeb | 127 | } |
richardparker | 6:4fe6f365cbeb | 128 | |
richardparker | 6:4fe6f365cbeb | 129 | // Get the size of the file. |
richardparker | 6:4fe6f365cbeb | 130 | fseek(fp, 0, SEEK_END); |
richardparker | 6:4fe6f365cbeb | 131 | long int size = ftell(fp); |
richardparker | 6:4fe6f365cbeb | 132 | |
richardparker | 6:4fe6f365cbeb | 133 | if (size == -1) |
richardparker | 6:4fe6f365cbeb | 134 | { |
richardparker | 6:4fe6f365cbeb | 135 | // Something went wronmg with the command. |
richardparker | 6:4fe6f365cbeb | 136 | return false; |
richardparker | 6:4fe6f365cbeb | 137 | } |
richardparker | 6:4fe6f365cbeb | 138 | |
richardparker | 6:4fe6f365cbeb | 139 | // Now create a cache large enough to hold all of the image data. |
richardparker | 6:4fe6f365cbeb | 140 | _cache = new char[size]; |
richardparker | 6:4fe6f365cbeb | 141 | |
richardparker | 6:4fe6f365cbeb | 142 | if (_cache == NULL) |
richardparker | 3:24fbf4dbd7e5 | 143 | { |
richardparker | 6:4fe6f365cbeb | 144 | // Unable to allocate enough space for the font. |
richardparker | 6:4fe6f365cbeb | 145 | return false; |
richardparker | 3:24fbf4dbd7e5 | 146 | } |
richardparker | 6:4fe6f365cbeb | 147 | |
richardparker | 6:4fe6f365cbeb | 148 | // Now rewind file pointer back to the beginning. |
richardparker | 6:4fe6f365cbeb | 149 | rewind(fp); |
richardparker | 6:4fe6f365cbeb | 150 | |
richardparker | 6:4fe6f365cbeb | 151 | const unsigned int CHUNK_SIZE = 100; |
richardparker | 6:4fe6f365cbeb | 152 | long int sizeRead = 0; |
richardparker | 6:4fe6f365cbeb | 153 | long int totalSizeRead = 0; |
richardparker | 6:4fe6f365cbeb | 154 | |
richardparker | 6:4fe6f365cbeb | 155 | // Load in small chunks at a time. |
richardparker | 6:4fe6f365cbeb | 156 | while (!feof(fp)) |
richardparker | 6:4fe6f365cbeb | 157 | { |
richardparker | 6:4fe6f365cbeb | 158 | // Read into the buffer. |
richardparker | 6:4fe6f365cbeb | 159 | sizeRead = fread(&_cache[totalSizeRead], 1, CHUNK_SIZE, fp); |
richardparker | 6:4fe6f365cbeb | 160 | |
richardparker | 6:4fe6f365cbeb | 161 | // Update total count of amount of data loaded. |
richardparker | 6:4fe6f365cbeb | 162 | totalSizeRead += sizeRead; |
richardparker | 6:4fe6f365cbeb | 163 | } |
richardparker | 6:4fe6f365cbeb | 164 | |
richardparker | 6:4fe6f365cbeb | 165 | // Check that the whole file loaded. |
richardparker | 6:4fe6f365cbeb | 166 | if (totalSizeRead != size) |
richardparker | 6:4fe6f365cbeb | 167 | { |
richardparker | 6:4fe6f365cbeb | 168 | // Clear cache. |
richardparker | 6:4fe6f365cbeb | 169 | delete[] _cache; |
richardparker | 6:4fe6f365cbeb | 170 | _cache = NULL; |
richardparker | 6:4fe6f365cbeb | 171 | |
richardparker | 6:4fe6f365cbeb | 172 | // Return error. |
richardparker | 6:4fe6f365cbeb | 173 | return false; |
richardparker | 6:4fe6f365cbeb | 174 | } |
richardparker | 6:4fe6f365cbeb | 175 | |
richardparker | 6:4fe6f365cbeb | 176 | // Record size and position. |
richardparker | 6:4fe6f365cbeb | 177 | _size = size; |
richardparker | 6:4fe6f365cbeb | 178 | _pos = 0L; |
richardparker | 6:4fe6f365cbeb | 179 | |
richardparker | 6:4fe6f365cbeb | 180 | return true; |
richardparker | 0:839ecbf5cb2a | 181 | } |
richardparker | 0:839ecbf5cb2a | 182 | |
richardparker | 1:f04bcaea1d60 | 183 | bool EAImage::_loadPalette(FILE* fp) |
richardparker | 1:f04bcaea1d60 | 184 | { |
richardparker | 6:4fe6f365cbeb | 185 | // Can't do anything with a null pointer unless cached. |
richardparker | 6:4fe6f365cbeb | 186 | if ((fp == NULL) && (isCached() == false)) |
richardparker | 1:f04bcaea1d60 | 187 | { |
richardparker | 1:f04bcaea1d60 | 188 | return false; |
richardparker | 1:f04bcaea1d60 | 189 | } |
richardparker | 1:f04bcaea1d60 | 190 | |
richardparker | 1:f04bcaea1d60 | 191 | // Clear any previously loaded palette. |
richardparker | 1:f04bcaea1d60 | 192 | if (_palette != NULL) |
richardparker | 1:f04bcaea1d60 | 193 | { |
richardparker | 1:f04bcaea1d60 | 194 | delete[] _palette; |
richardparker | 1:f04bcaea1d60 | 195 | _palette = NULL; |
richardparker | 1:f04bcaea1d60 | 196 | } |
richardparker | 1:f04bcaea1d60 | 197 | |
richardparker | 1:f04bcaea1d60 | 198 | // If the number of bits is not less than 16 then return after having cleared the |
richardparker | 1:f04bcaea1d60 | 199 | // palette. There is no palette required. |
richardparker | 1:f04bcaea1d60 | 200 | if (info().bitsPerPixel >= 16) |
richardparker | 1:f04bcaea1d60 | 201 | { |
richardparker | 1:f04bcaea1d60 | 202 | return true; |
richardparker | 1:f04bcaea1d60 | 203 | } |
richardparker | 1:f04bcaea1d60 | 204 | |
richardparker | 1:f04bcaea1d60 | 205 | // First create a palette of the required size. |
richardparker | 1:f04bcaea1d60 | 206 | unsigned int noColors = info().noColors; |
richardparker | 1:f04bcaea1d60 | 207 | |
richardparker | 1:f04bcaea1d60 | 208 | // When 0 the number of colors is equal to 2^n where n is the bits per pixel. |
richardparker | 1:f04bcaea1d60 | 209 | if (noColors == 0) |
richardparker | 1:f04bcaea1d60 | 210 | { |
richardparker | 1:f04bcaea1d60 | 211 | noColors = pow((double)2, info().bitsPerPixel); |
richardparker | 1:f04bcaea1d60 | 212 | } |
richardparker | 1:f04bcaea1d60 | 213 | |
richardparker | 1:f04bcaea1d60 | 214 | // Create the palette and assign the memory. |
richardparker | 1:f04bcaea1d60 | 215 | _palette = new EAColor[noColors]; |
richardparker | 1:f04bcaea1d60 | 216 | |
richardparker | 1:f04bcaea1d60 | 217 | // Now parse the palette. First seek to the start of the palette. This must be the |
richardparker | 1:f04bcaea1d60 | 218 | // start of the bitmap data minus the number of colour entries multiplied by 4 (the |
richardparker | 1:f04bcaea1d60 | 219 | // colours are stored as 4 byte long entries, the last byte can be ignored). |
richardparker | 1:f04bcaea1d60 | 220 | unsigned int offset = _dataOffset - (noColors*4); |
richardparker | 1:f04bcaea1d60 | 221 | |
richardparker | 1:f04bcaea1d60 | 222 | // Seek to the start of the table. |
richardparker | 6:4fe6f365cbeb | 223 | _fseek(fp, offset, SEEK_SET); |
richardparker | 1:f04bcaea1d60 | 224 | unsigned char buffer[4]; |
richardparker | 1:f04bcaea1d60 | 225 | |
richardparker | 1:f04bcaea1d60 | 226 | // Iterate through the table filling the palette as needed. |
richardparker | 1:f04bcaea1d60 | 227 | for (int i = 0; i < noColors; i++) |
richardparker | 1:f04bcaea1d60 | 228 | { |
richardparker | 6:4fe6f365cbeb | 229 | int sizeRead = _fread(&buffer, 4, 1, fp); |
richardparker | 1:f04bcaea1d60 | 230 | |
richardparker | 1:f04bcaea1d60 | 231 | if (sizeRead == 1) |
richardparker | 1:f04bcaea1d60 | 232 | { |
richardparker | 1:f04bcaea1d60 | 233 | _palette[i].setRgb(buffer[2], buffer[1], buffer[0]); |
richardparker | 1:f04bcaea1d60 | 234 | } |
richardparker | 1:f04bcaea1d60 | 235 | } |
richardparker | 1:f04bcaea1d60 | 236 | |
richardparker | 1:f04bcaea1d60 | 237 | return true; |
richardparker | 1:f04bcaea1d60 | 238 | } |
richardparker | 1:f04bcaea1d60 | 239 | |
richardparker | 0:839ecbf5cb2a | 240 | bool EAImage::_loadHeader(const char* path) |
richardparker | 0:839ecbf5cb2a | 241 | { |
richardparker | 0:839ecbf5cb2a | 242 | if (path == NULL) |
richardparker | 0:839ecbf5cb2a | 243 | { |
richardparker | 0:839ecbf5cb2a | 244 | // Invalid path passed in. |
richardparker | 0:839ecbf5cb2a | 245 | return false; |
richardparker | 0:839ecbf5cb2a | 246 | } |
richardparker | 0:839ecbf5cb2a | 247 | |
richardparker | 0:839ecbf5cb2a | 248 | // Try and open the file, check type and load width and height. |
richardparker | 0:839ecbf5cb2a | 249 | FILE* fp = fopen(path, "r"); |
richardparker | 0:839ecbf5cb2a | 250 | if (fp == NULL) |
richardparker | 0:839ecbf5cb2a | 251 | { |
richardparker | 0:839ecbf5cb2a | 252 | return false; |
richardparker | 0:839ecbf5cb2a | 253 | } |
richardparker | 0:839ecbf5cb2a | 254 | |
richardparker | 0:839ecbf5cb2a | 255 | unsigned int bufint = 0; |
richardparker | 0:839ecbf5cb2a | 256 | unsigned int offset = 0; |
richardparker | 0:839ecbf5cb2a | 257 | |
richardparker | 0:839ecbf5cb2a | 258 | // Read the magic numbers at start. |
richardparker | 0:839ecbf5cb2a | 259 | fread(&bufint, 1, 2, fp); |
richardparker | 0:839ecbf5cb2a | 260 | if (bufint != 0x4d42) |
richardparker | 0:839ecbf5cb2a | 261 | { |
richardparker | 0:839ecbf5cb2a | 262 | // Clean up file handle. |
richardparker | 0:839ecbf5cb2a | 263 | fclose(fp); |
richardparker | 6:4fe6f365cbeb | 264 | unload(); |
richardparker | 0:839ecbf5cb2a | 265 | |
richardparker | 0:839ecbf5cb2a | 266 | // Header incorrect. |
richardparker | 0:839ecbf5cb2a | 267 | return false; |
richardparker | 0:839ecbf5cb2a | 268 | } |
richardparker | 0:839ecbf5cb2a | 269 | |
richardparker | 0:839ecbf5cb2a | 270 | // Now read the bmp file size. |
richardparker | 0:839ecbf5cb2a | 271 | fread(&bufint, 1, 4, fp); |
richardparker | 0:839ecbf5cb2a | 272 | |
richardparker | 0:839ecbf5cb2a | 273 | // Now read the two creator values and throw away. |
richardparker | 0:839ecbf5cb2a | 274 | fread(&bufint, 1, 2, fp); |
richardparker | 0:839ecbf5cb2a | 275 | fread(&bufint, 1, 2, fp); |
richardparker | 0:839ecbf5cb2a | 276 | |
richardparker | 0:839ecbf5cb2a | 277 | // Now read the offset for the bitmap data. |
richardparker | 0:839ecbf5cb2a | 278 | fread(&bufint, 1, 4, fp); |
richardparker | 0:839ecbf5cb2a | 279 | offset = bufint; |
richardparker | 0:839ecbf5cb2a | 280 | |
richardparker | 0:839ecbf5cb2a | 281 | // Retrieve the header. |
richardparker | 1:f04bcaea1d60 | 282 | fread(&_header, sizeof(EABMPHeader), 1, fp); |
richardparker | 0:839ecbf5cb2a | 283 | |
richardparker | 1:f04bcaea1d60 | 284 | // Make sure the compression type is a value that can be dealt with. |
richardparker | 1:f04bcaea1d60 | 285 | if ((info().compressionType != 3) && (info().compressionType != 0)) |
richardparker | 1:f04bcaea1d60 | 286 | { |
richardparker | 0:839ecbf5cb2a | 287 | // Clean up file handle. |
richardparker | 6:4fe6f365cbeb | 288 | fclose(fp); |
richardparker | 6:4fe6f365cbeb | 289 | unload(); |
richardparker | 0:839ecbf5cb2a | 290 | |
richardparker | 0:839ecbf5cb2a | 291 | // Header incorrect. |
richardparker | 0:839ecbf5cb2a | 292 | return false; |
richardparker | 0:839ecbf5cb2a | 293 | } |
richardparker | 0:839ecbf5cb2a | 294 | |
richardparker | 0:839ecbf5cb2a | 295 | // Set the values for later. |
richardparker | 0:839ecbf5cb2a | 296 | _dataOffset = offset; |
richardparker | 1:f04bcaea1d60 | 297 | setWidth(info().width); |
richardparker | 1:f04bcaea1d60 | 298 | setHeight(info().height); |
richardparker | 6:4fe6f365cbeb | 299 | |
richardparker | 6:4fe6f365cbeb | 300 | // If the image is to be cached then load the cache. |
richardparker | 6:4fe6f365cbeb | 301 | if (_loadCache(fp) == false) |
richardparker | 6:4fe6f365cbeb | 302 | { |
richardparker | 6:4fe6f365cbeb | 303 | // Clean up file handle. |
richardparker | 6:4fe6f365cbeb | 304 | fclose(fp); |
richardparker | 6:4fe6f365cbeb | 305 | unload(); |
richardparker | 6:4fe6f365cbeb | 306 | |
richardparker | 6:4fe6f365cbeb | 307 | // Header incorrect. |
richardparker | 6:4fe6f365cbeb | 308 | return false; |
richardparker | 6:4fe6f365cbeb | 309 | } |
richardparker | 1:f04bcaea1d60 | 310 | |
richardparker | 0:839ecbf5cb2a | 311 | // Close the file. |
richardparker | 0:839ecbf5cb2a | 312 | fclose(fp); |
richardparker | 0:839ecbf5cb2a | 313 | |
richardparker | 0:839ecbf5cb2a | 314 | return true; |
richardparker | 0:839ecbf5cb2a | 315 | } |
richardparker | 0:839ecbf5cb2a | 316 | |
richardparker | 1:f04bcaea1d60 | 317 | int EAImage::_wordsInRow() |
richardparker | 1:f04bcaea1d60 | 318 | { |
richardparker | 1:f04bcaea1d60 | 319 | // If there were no padding to 32 bit boundaries this would be the number of bits per row |
richardparker | 1:f04bcaea1d60 | 320 | // in the file. |
richardparker | 1:f04bcaea1d60 | 321 | int bitsPerWidth = width() * info().bitsPerPixel; |
richardparker | 1:f04bcaea1d60 | 322 | |
richardparker | 1:f04bcaea1d60 | 323 | // This is the row size with padding on the end. |
richardparker | 1:f04bcaea1d60 | 324 | int remainder = (bitsPerWidth % 32); |
richardparker | 1:f04bcaea1d60 | 325 | int bitsPerRow = (remainder == 0) ? bitsPerWidth : bitsPerWidth + (32 - remainder); |
richardparker | 1:f04bcaea1d60 | 326 | |
richardparker | 1:f04bcaea1d60 | 327 | // Return the size in number of words. |
richardparker | 1:f04bcaea1d60 | 328 | return (bitsPerRow / 32); |
richardparker | 1:f04bcaea1d60 | 329 | } |
richardparker | 1:f04bcaea1d60 | 330 | |
richardparker | 1:f04bcaea1d60 | 331 | int EAImage::_wordForX(unsigned int x) |
richardparker | 1:f04bcaea1d60 | 332 | { |
richardparker | 1:f04bcaea1d60 | 333 | int bitForX = x * info().bitsPerPixel; |
richardparker | 1:f04bcaea1d60 | 334 | |
richardparker | 1:f04bcaea1d60 | 335 | return (bitForX / 32); |
richardparker | 1:f04bcaea1d60 | 336 | } |
richardparker | 1:f04bcaea1d60 | 337 | |
richardparker | 1:f04bcaea1d60 | 338 | int EAImage::_xWordOffset(unsigned int x) |
richardparker | 1:f04bcaea1d60 | 339 | { |
richardparker | 1:f04bcaea1d60 | 340 | int bitForX = x * info().bitsPerPixel; |
richardparker | 1:f04bcaea1d60 | 341 | |
richardparker | 1:f04bcaea1d60 | 342 | return (bitForX % 32); |
richardparker | 1:f04bcaea1d60 | 343 | } |
richardparker | 1:f04bcaea1d60 | 344 | |
richardparker | 1:f04bcaea1d60 | 345 | unsigned short EAImage::_getColourAtOffset(unsigned int word, int offset) |
richardparker | 1:f04bcaea1d60 | 346 | { |
richardparker | 1:f04bcaea1d60 | 347 | // Sort bytes for endianness. |
richardparker | 1:f04bcaea1d60 | 348 | unsigned char* cptr; |
richardparker | 1:f04bcaea1d60 | 349 | unsigned short result = 0x0000; |
richardparker | 1:f04bcaea1d60 | 350 | |
richardparker | 1:f04bcaea1d60 | 351 | // Now need to decide how to cast the value to a colour. |
richardparker | 1:f04bcaea1d60 | 352 | switch (info().bitsPerPixel) |
richardparker | 1:f04bcaea1d60 | 353 | { |
richardparker | 1:f04bcaea1d60 | 354 | // Swap the bytes around. |
richardparker | 1:f04bcaea1d60 | 355 | case 32: |
richardparker | 1:f04bcaea1d60 | 356 | case 4: |
richardparker | 1:f04bcaea1d60 | 357 | case 8: |
richardparker | 1:f04bcaea1d60 | 358 | case 1: |
richardparker | 1:f04bcaea1d60 | 359 | unsigned char tmp; |
richardparker | 1:f04bcaea1d60 | 360 | cptr = (unsigned char*)&word; |
richardparker | 1:f04bcaea1d60 | 361 | tmp = cptr[0]; |
richardparker | 1:f04bcaea1d60 | 362 | cptr[0] = cptr[3]; |
richardparker | 1:f04bcaea1d60 | 363 | cptr[3] = tmp; |
richardparker | 1:f04bcaea1d60 | 364 | tmp = cptr[1]; |
richardparker | 1:f04bcaea1d60 | 365 | cptr[1] = cptr[2]; |
richardparker | 1:f04bcaea1d60 | 366 | cptr[2] = tmp; |
richardparker | 1:f04bcaea1d60 | 367 | break; |
richardparker | 1:f04bcaea1d60 | 368 | |
richardparker | 1:f04bcaea1d60 | 369 | default: |
richardparker | 1:f04bcaea1d60 | 370 | // Swap the 16bits around. |
richardparker | 1:f04bcaea1d60 | 371 | case 16: |
richardparker | 1:f04bcaea1d60 | 372 | unsigned char tmpa; |
richardparker | 1:f04bcaea1d60 | 373 | unsigned char tmpb; |
richardparker | 1:f04bcaea1d60 | 374 | cptr = (unsigned char*)&word; |
richardparker | 1:f04bcaea1d60 | 375 | tmpa = cptr[1]; |
richardparker | 1:f04bcaea1d60 | 376 | tmpb = cptr[0]; |
richardparker | 1:f04bcaea1d60 | 377 | cptr[1] = cptr[3]; |
richardparker | 1:f04bcaea1d60 | 378 | cptr[0] = cptr[2]; |
richardparker | 1:f04bcaea1d60 | 379 | cptr[3] = tmpa; |
richardparker | 1:f04bcaea1d60 | 380 | cptr[2] = tmpb; |
richardparker | 1:f04bcaea1d60 | 381 | break; |
richardparker | 1:f04bcaea1d60 | 382 | } |
richardparker | 1:f04bcaea1d60 | 383 | |
richardparker | 1:f04bcaea1d60 | 384 | // First shift off the pixels above. |
richardparker | 1:f04bcaea1d60 | 385 | word = word << offset; |
richardparker | 1:f04bcaea1d60 | 386 | |
richardparker | 1:f04bcaea1d60 | 387 | // Now shift down so that pixel is in lsb. |
richardparker | 1:f04bcaea1d60 | 388 | word = word >> (32 - info().bitsPerPixel); |
richardparker | 1:f04bcaea1d60 | 389 | |
richardparker | 1:f04bcaea1d60 | 390 | EAColor c; |
richardparker | 1:f04bcaea1d60 | 391 | |
richardparker | 1:f04bcaea1d60 | 392 | // Now need to decide how to cast the value to a colour. |
richardparker | 1:f04bcaea1d60 | 393 | switch (info().bitsPerPixel) |
richardparker | 1:f04bcaea1d60 | 394 | { |
richardparker | 1:f04bcaea1d60 | 395 | case 8: |
richardparker | 1:f04bcaea1d60 | 396 | case 4: |
richardparker | 1:f04bcaea1d60 | 397 | case 1: |
richardparker | 1:f04bcaea1d60 | 398 | if (_palette != NULL) |
richardparker | 1:f04bcaea1d60 | 399 | { |
richardparker | 1:f04bcaea1d60 | 400 | result = _palette[word].rawValue(); |
richardparker | 1:f04bcaea1d60 | 401 | } else { |
richardparker | 1:f04bcaea1d60 | 402 | result = 0x0000; |
richardparker | 1:f04bcaea1d60 | 403 | } |
richardparker | 1:f04bcaea1d60 | 404 | break; |
richardparker | 1:f04bcaea1d60 | 405 | |
richardparker | 1:f04bcaea1d60 | 406 | // By default just cast to unsigned short and return. |
richardparker | 1:f04bcaea1d60 | 407 | default: |
richardparker | 1:f04bcaea1d60 | 408 | case 16: |
richardparker | 1:f04bcaea1d60 | 409 | result = (unsigned short)(word); |
richardparker | 1:f04bcaea1d60 | 410 | break; |
richardparker | 1:f04bcaea1d60 | 411 | |
richardparker | 1:f04bcaea1d60 | 412 | case 24: |
richardparker | 1:f04bcaea1d60 | 413 | case 32: |
richardparker | 1:f04bcaea1d60 | 414 | unsigned char b = ((word << 0) >> 24); |
richardparker | 1:f04bcaea1d60 | 415 | unsigned char g = ((word << 8) >> 24); |
richardparker | 1:f04bcaea1d60 | 416 | unsigned char r = ((word << 16) >> 24); |
richardparker | 1:f04bcaea1d60 | 417 | |
richardparker | 1:f04bcaea1d60 | 418 | c.setRgb(r, g, b); |
richardparker | 1:f04bcaea1d60 | 419 | result = c.rawValue(); |
richardparker | 1:f04bcaea1d60 | 420 | break; |
richardparker | 1:f04bcaea1d60 | 421 | } |
richardparker | 1:f04bcaea1d60 | 422 | |
richardparker | 1:f04bcaea1d60 | 423 | return result; |
richardparker | 1:f04bcaea1d60 | 424 | } |
richardparker | 1:f04bcaea1d60 | 425 | |
richardparker | 0:839ecbf5cb2a | 426 | bool EAImage::load(const char* path) |
richardparker | 0:839ecbf5cb2a | 427 | { |
richardparker | 0:839ecbf5cb2a | 428 | if (path == NULL) |
richardparker | 0:839ecbf5cb2a | 429 | { |
richardparker | 1:f04bcaea1d60 | 430 | // Reset all of the state. |
richardparker | 1:f04bcaea1d60 | 431 | unload(); |
richardparker | 1:f04bcaea1d60 | 432 | |
richardparker | 0:839ecbf5cb2a | 433 | // Invalid path passed in. |
richardparker | 0:839ecbf5cb2a | 434 | return false; |
richardparker | 0:839ecbf5cb2a | 435 | } |
richardparker | 0:839ecbf5cb2a | 436 | |
richardparker | 0:839ecbf5cb2a | 437 | if (_loadHeader(path) == false) |
richardparker | 0:839ecbf5cb2a | 438 | { |
richardparker | 1:f04bcaea1d60 | 439 | // Reset all of the state. |
richardparker | 1:f04bcaea1d60 | 440 | unload(); |
richardparker | 1:f04bcaea1d60 | 441 | |
richardparker | 0:839ecbf5cb2a | 442 | return false; |
richardparker | 0:839ecbf5cb2a | 443 | } |
richardparker | 0:839ecbf5cb2a | 444 | |
richardparker | 0:839ecbf5cb2a | 445 | int pathLen = strlen(path); |
richardparker | 0:839ecbf5cb2a | 446 | |
richardparker | 0:839ecbf5cb2a | 447 | // If already loaded an image then clear to load the new one. |
richardparker | 0:839ecbf5cb2a | 448 | if (_path != NULL) |
richardparker | 0:839ecbf5cb2a | 449 | { |
richardparker | 0:839ecbf5cb2a | 450 | delete[] _path; |
richardparker | 0:839ecbf5cb2a | 451 | _path = NULL; |
richardparker | 0:839ecbf5cb2a | 452 | } |
richardparker | 0:839ecbf5cb2a | 453 | |
richardparker | 0:839ecbf5cb2a | 454 | // Now allocate enough space to hold path. Note +1 for null character. |
richardparker | 0:839ecbf5cb2a | 455 | _path = new char[pathLen+1]; |
richardparker | 0:839ecbf5cb2a | 456 | |
richardparker | 0:839ecbf5cb2a | 457 | // Now copy over passed in path to path variable. |
richardparker | 0:839ecbf5cb2a | 458 | strcpy(_path, path); |
richardparker | 0:839ecbf5cb2a | 459 | |
richardparker | 0:839ecbf5cb2a | 460 | // Image loaded successfully. |
richardparker | 0:839ecbf5cb2a | 461 | return true; |
richardparker | 0:839ecbf5cb2a | 462 | } |
richardparker | 0:839ecbf5cb2a | 463 | |
richardparker | 1:f04bcaea1d60 | 464 | void EAImage::unload() |
richardparker | 1:f04bcaea1d60 | 465 | { |
richardparker | 1:f04bcaea1d60 | 466 | // Empty the header struct. |
richardparker | 1:f04bcaea1d60 | 467 | _header.headerSize = 0; |
richardparker | 1:f04bcaea1d60 | 468 | _header.width = 0; |
richardparker | 1:f04bcaea1d60 | 469 | _header.height = 0; |
richardparker | 1:f04bcaea1d60 | 470 | _header.noColorPlanes = 0; |
richardparker | 1:f04bcaea1d60 | 471 | _header.bitsPerPixel = 0; |
richardparker | 1:f04bcaea1d60 | 472 | _header.compressionType = 0; |
richardparker | 1:f04bcaea1d60 | 473 | _header.bmpSize = 0; |
richardparker | 1:f04bcaea1d60 | 474 | _header.horizontalRes = 0; |
richardparker | 1:f04bcaea1d60 | 475 | _header.verticalRes = 0; |
richardparker | 1:f04bcaea1d60 | 476 | _header.noColors = 0; |
richardparker | 1:f04bcaea1d60 | 477 | _header.noImportantColors = 0; |
richardparker | 1:f04bcaea1d60 | 478 | |
richardparker | 1:f04bcaea1d60 | 479 | // Clear the path. |
richardparker | 1:f04bcaea1d60 | 480 | if (_path != NULL) |
richardparker | 1:f04bcaea1d60 | 481 | { |
richardparker | 1:f04bcaea1d60 | 482 | delete[] _path; |
richardparker | 1:f04bcaea1d60 | 483 | _path = NULL; |
richardparker | 1:f04bcaea1d60 | 484 | } |
richardparker | 1:f04bcaea1d60 | 485 | |
richardparker | 1:f04bcaea1d60 | 486 | // Clear the palette. |
richardparker | 1:f04bcaea1d60 | 487 | if (_palette != NULL) |
richardparker | 1:f04bcaea1d60 | 488 | { |
richardparker | 1:f04bcaea1d60 | 489 | delete[] _palette; |
richardparker | 1:f04bcaea1d60 | 490 | _palette = NULL; |
richardparker | 1:f04bcaea1d60 | 491 | } |
richardparker | 1:f04bcaea1d60 | 492 | |
richardparker | 1:f04bcaea1d60 | 493 | // Clear the data offset. |
richardparker | 1:f04bcaea1d60 | 494 | _dataOffset = 0; |
richardparker | 1:f04bcaea1d60 | 495 | |
richardparker | 1:f04bcaea1d60 | 496 | // Set the size to 0. |
richardparker | 1:f04bcaea1d60 | 497 | setWidth(0); |
richardparker | 1:f04bcaea1d60 | 498 | setHeight(0); |
richardparker | 1:f04bcaea1d60 | 499 | |
richardparker | 6:4fe6f365cbeb | 500 | // Empty the cache. |
richardparker | 6:4fe6f365cbeb | 501 | if (_cache != NULL) |
richardparker | 6:4fe6f365cbeb | 502 | { |
richardparker | 6:4fe6f365cbeb | 503 | delete[] _cache; |
richardparker | 6:4fe6f365cbeb | 504 | _cache = NULL; |
richardparker | 6:4fe6f365cbeb | 505 | } |
richardparker | 6:4fe6f365cbeb | 506 | _size = 0L; |
richardparker | 6:4fe6f365cbeb | 507 | _pos = 0L; |
richardparker | 1:f04bcaea1d60 | 508 | } |
richardparker | 1:f04bcaea1d60 | 509 | |
richardparker | 0:839ecbf5cb2a | 510 | void EAImage::paint(EALCD& lcd) |
richardparker | 0:839ecbf5cb2a | 511 | { |
richardparker | 0:839ecbf5cb2a | 512 | paint(lcd, 0, 0, width(), height()); |
richardparker | 0:839ecbf5cb2a | 513 | } |
richardparker | 0:839ecbf5cb2a | 514 | |
richardparker | 0:839ecbf5cb2a | 515 | void EAImage::paint(EALCD& lcd, unsigned int x, unsigned int y, unsigned int w, unsigned int h) |
richardparker | 0:839ecbf5cb2a | 516 | { |
richardparker | 0:839ecbf5cb2a | 517 | if (isValid() == false) |
richardparker | 0:839ecbf5cb2a | 518 | { |
richardparker | 0:839ecbf5cb2a | 519 | return; |
richardparker | 0:839ecbf5cb2a | 520 | } |
richardparker | 0:839ecbf5cb2a | 521 | |
richardparker | 0:839ecbf5cb2a | 522 | // Don't allow draw out of range. |
richardparker | 0:839ecbf5cb2a | 523 | if (x + w > width()) |
richardparker | 0:839ecbf5cb2a | 524 | { |
richardparker | 0:839ecbf5cb2a | 525 | return; |
richardparker | 0:839ecbf5cb2a | 526 | } |
richardparker | 0:839ecbf5cb2a | 527 | |
richardparker | 0:839ecbf5cb2a | 528 | if (y + h > height()) |
richardparker | 0:839ecbf5cb2a | 529 | { |
richardparker | 0:839ecbf5cb2a | 530 | return; |
richardparker | 0:839ecbf5cb2a | 531 | } |
richardparker | 0:839ecbf5cb2a | 532 | |
richardparker | 1:f04bcaea1d60 | 533 | // Buffer to hold load one line at a time this must be large enough to hold all of the data used |
richardparker | 1:f04bcaea1d60 | 534 | // 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 | 535 | // 32 bit boundary. |
richardparker | 1:f04bcaea1d60 | 536 | int wordsInRow = _wordsInRow(); |
richardparker | 1:f04bcaea1d60 | 537 | unsigned int buffer[wordsInRow]; |
richardparker | 0:839ecbf5cb2a | 538 | int xD = 0; |
richardparker | 0:839ecbf5cb2a | 539 | int yD = 0; |
richardparker | 1:f04bcaea1d60 | 540 | int wordOffset = 0; |
richardparker | 1:f04bcaea1d60 | 541 | int bitsPerPixel = info().bitsPerPixel; |
richardparker | 1:f04bcaea1d60 | 542 | unsigned short data = 0; |
richardparker | 0:839ecbf5cb2a | 543 | |
richardparker | 0:839ecbf5cb2a | 544 | // Try and open the file, skip straight to the data. |
richardparker | 6:4fe6f365cbeb | 545 | FILE* fp = NULL; |
richardparker | 6:4fe6f365cbeb | 546 | if (isCached() == false) |
richardparker | 0:839ecbf5cb2a | 547 | { |
richardparker | 6:4fe6f365cbeb | 548 | fp = fopen(_path, "r"); |
richardparker | 6:4fe6f365cbeb | 549 | if (fp == NULL) |
richardparker | 6:4fe6f365cbeb | 550 | { |
richardparker | 6:4fe6f365cbeb | 551 | return; |
richardparker | 6:4fe6f365cbeb | 552 | } |
richardparker | 6:4fe6f365cbeb | 553 | } |
richardparker | 6:4fe6f365cbeb | 554 | |
richardparker | 6:4fe6f365cbeb | 555 | // If the bits per pixel are less than 16 then the bitmap is using a colour |
richardparker | 6:4fe6f365cbeb | 556 | // palette which should be loaded first. |
richardparker | 6:4fe6f365cbeb | 557 | if (_loadPalette(fp) == false) |
richardparker | 6:4fe6f365cbeb | 558 | { |
richardparker | 6:4fe6f365cbeb | 559 | if (isCached() == false) |
richardparker | 6:4fe6f365cbeb | 560 | { |
richardparker | 6:4fe6f365cbeb | 561 | fclose(fp); |
richardparker | 6:4fe6f365cbeb | 562 | } |
richardparker | 6:4fe6f365cbeb | 563 | |
richardparker | 0:839ecbf5cb2a | 564 | return; |
richardparker | 0:839ecbf5cb2a | 565 | } |
richardparker | 0:839ecbf5cb2a | 566 | |
richardparker | 0:839ecbf5cb2a | 567 | // Skip the header and size. |
richardparker | 6:4fe6f365cbeb | 568 | _fseek(fp, _dataOffset, SEEK_SET); |
richardparker | 0:839ecbf5cb2a | 569 | |
richardparker | 0:839ecbf5cb2a | 570 | // Prepare the lcd for drawing. |
richardparker | 0:839ecbf5cb2a | 571 | lcd._window(this->x(), this->y(), w, h); |
richardparker | 0:839ecbf5cb2a | 572 | lcd._moveTo(this->x(), this->y()); |
richardparker | 0:839ecbf5cb2a | 573 | |
richardparker | 0:839ecbf5cb2a | 574 | // Move in the file to the first pixel in the window. |
richardparker | 6:4fe6f365cbeb | 575 | _fseek(fp, (y*wordsInRow*4)+(_wordForX(x)*4), SEEK_CUR); |
richardparker | 1:f04bcaea1d60 | 576 | |
richardparker | 0:839ecbf5cb2a | 577 | // Now read the data. |
richardparker | 6:4fe6f365cbeb | 578 | while (!_feof(fp)) |
richardparker | 0:839ecbf5cb2a | 579 | { |
richardparker | 1:f04bcaea1d60 | 580 | wordOffset = _xWordOffset(x); |
richardparker | 1:f04bcaea1d60 | 581 | |
richardparker | 6:4fe6f365cbeb | 582 | int sizeRead = _fread(&buffer, 4, wordsInRow, fp); |
richardparker | 0:839ecbf5cb2a | 583 | |
richardparker | 0:839ecbf5cb2a | 584 | for (int i = 0; i < sizeRead; i++) |
richardparker | 1:f04bcaea1d60 | 585 | { |
richardparker | 1:f04bcaea1d60 | 586 | while (wordOffset < 32) |
richardparker | 1:f04bcaea1d60 | 587 | { |
richardparker | 1:f04bcaea1d60 | 588 | // Convert the colour to a 16 bit colour value that can be written directly to the screen. |
richardparker | 1:f04bcaea1d60 | 589 | data = _getColourAtOffset(buffer[i], wordOffset); |
richardparker | 6:4fe6f365cbeb | 590 | |
richardparker | 1:f04bcaea1d60 | 591 | if (isMask() == true) |
richardparker | 1:f04bcaea1d60 | 592 | { |
richardparker | 1:f04bcaea1d60 | 593 | // When a mask the 0x0000 value is transparent anything else is drawn with the pen color. |
richardparker | 1:f04bcaea1d60 | 594 | if (data == 0x0000) |
richardparker | 1:f04bcaea1d60 | 595 | { |
richardparker | 1:f04bcaea1d60 | 596 | lcd.noop(); |
richardparker | 1:f04bcaea1d60 | 597 | } else { |
richardparker | 1:f04bcaea1d60 | 598 | lcd._writeToDisplay(lcd.pen().color().rawValue()); |
richardparker | 1:f04bcaea1d60 | 599 | } |
richardparker | 6:4fe6f365cbeb | 600 | } else { |
richardparker | 1:f04bcaea1d60 | 601 | // Not a mask so just use colour that have loaded. |
richardparker | 1:f04bcaea1d60 | 602 | lcd._writeToDisplay(data); |
richardparker | 1:f04bcaea1d60 | 603 | } |
richardparker | 1:f04bcaea1d60 | 604 | |
richardparker | 1:f04bcaea1d60 | 605 | // Got to next pixel in the word. |
richardparker | 1:f04bcaea1d60 | 606 | wordOffset += bitsPerPixel; |
richardparker | 1:f04bcaea1d60 | 607 | |
richardparker | 1:f04bcaea1d60 | 608 | // Keep count of current x value. |
richardparker | 1:f04bcaea1d60 | 609 | xD++; |
richardparker | 1:f04bcaea1d60 | 610 | if (xD == w) |
richardparker | 1:f04bcaea1d60 | 611 | { |
richardparker | 1:f04bcaea1d60 | 612 | break; |
richardparker | 1:f04bcaea1d60 | 613 | } |
richardparker | 1:f04bcaea1d60 | 614 | } |
richardparker | 1:f04bcaea1d60 | 615 | wordOffset = 0; |
richardparker | 0:839ecbf5cb2a | 616 | |
richardparker | 1:f04bcaea1d60 | 617 | // When written all required pixels exit. |
richardparker | 0:839ecbf5cb2a | 618 | if (xD == w) |
richardparker | 0:839ecbf5cb2a | 619 | { |
richardparker | 0:839ecbf5cb2a | 620 | xD = 0; |
richardparker | 0:839ecbf5cb2a | 621 | break; |
richardparker | 0:839ecbf5cb2a | 622 | } |
richardparker | 0:839ecbf5cb2a | 623 | } |
richardparker | 0:839ecbf5cb2a | 624 | |
richardparker | 0:839ecbf5cb2a | 625 | // Keep count of curernt y value. |
richardparker | 0:839ecbf5cb2a | 626 | yD++; |
richardparker | 0:839ecbf5cb2a | 627 | if (yD == h) |
richardparker | 0:839ecbf5cb2a | 628 | { |
richardparker | 0:839ecbf5cb2a | 629 | break; |
richardparker | 0:839ecbf5cb2a | 630 | } |
richardparker | 0:839ecbf5cb2a | 631 | } |
richardparker | 0:839ecbf5cb2a | 632 | |
richardparker | 1:f04bcaea1d60 | 633 | // Clear the palette. |
richardparker | 1:f04bcaea1d60 | 634 | if (_palette != NULL) |
richardparker | 1:f04bcaea1d60 | 635 | { |
richardparker | 1:f04bcaea1d60 | 636 | delete[] _palette; |
richardparker | 1:f04bcaea1d60 | 637 | _palette = NULL; |
richardparker | 1:f04bcaea1d60 | 638 | } |
richardparker | 1:f04bcaea1d60 | 639 | |
richardparker | 6:4fe6f365cbeb | 640 | if (isCached() == false) |
richardparker | 6:4fe6f365cbeb | 641 | { |
richardparker | 6:4fe6f365cbeb | 642 | // Close the file and release handle. |
richardparker | 6:4fe6f365cbeb | 643 | fclose(fp); |
richardparker | 6:4fe6f365cbeb | 644 | } |
richardparker | 0:839ecbf5cb2a | 645 | } |
richardparker | 0:839ecbf5cb2a | 646 | |
richardparker | 0:839ecbf5cb2a | 647 |