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@0:839ecbf5cb2a, 2010-02-11 (annotated)
- Committer:
- richardparker
- Date:
- Thu Feb 11 12:21:18 2010 +0000
- Revision:
- 0:839ecbf5cb2a
- Child:
- 1:f04bcaea1d60
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 | 0:839ecbf5cb2a | 13 | _dataOffset(0) |
richardparker | 0:839ecbf5cb2a | 14 | { |
richardparker | 0:839ecbf5cb2a | 15 | } |
richardparker | 0:839ecbf5cb2a | 16 | |
richardparker | 0:839ecbf5cb2a | 17 | EAImage::~EAImage() |
richardparker | 0:839ecbf5cb2a | 18 | { |
richardparker | 0:839ecbf5cb2a | 19 | } |
richardparker | 0:839ecbf5cb2a | 20 | |
richardparker | 0:839ecbf5cb2a | 21 | bool EAImage::_loadHeader(const char* path) |
richardparker | 0:839ecbf5cb2a | 22 | { |
richardparker | 0:839ecbf5cb2a | 23 | if (path == NULL) |
richardparker | 0:839ecbf5cb2a | 24 | { |
richardparker | 0:839ecbf5cb2a | 25 | // Invalid path passed in. |
richardparker | 0:839ecbf5cb2a | 26 | return false; |
richardparker | 0:839ecbf5cb2a | 27 | } |
richardparker | 0:839ecbf5cb2a | 28 | |
richardparker | 0:839ecbf5cb2a | 29 | // Try and open the file, check type and load width and height. |
richardparker | 0:839ecbf5cb2a | 30 | FILE* fp = fopen(path, "r"); |
richardparker | 0:839ecbf5cb2a | 31 | if (fp == NULL) |
richardparker | 0:839ecbf5cb2a | 32 | { |
richardparker | 0:839ecbf5cb2a | 33 | return false; |
richardparker | 0:839ecbf5cb2a | 34 | } |
richardparker | 0:839ecbf5cb2a | 35 | |
richardparker | 0:839ecbf5cb2a | 36 | unsigned int bufint = 0; |
richardparker | 0:839ecbf5cb2a | 37 | unsigned int offset = 0; |
richardparker | 0:839ecbf5cb2a | 38 | EABMPHeader header; |
richardparker | 0:839ecbf5cb2a | 39 | |
richardparker | 0:839ecbf5cb2a | 40 | // Read the magic numbers at start. |
richardparker | 0:839ecbf5cb2a | 41 | fread(&bufint, 1, 2, fp); |
richardparker | 0:839ecbf5cb2a | 42 | if (bufint != 0x4d42) |
richardparker | 0:839ecbf5cb2a | 43 | { |
richardparker | 0:839ecbf5cb2a | 44 | // Clean up file handle. |
richardparker | 0:839ecbf5cb2a | 45 | fclose(fp); |
richardparker | 0:839ecbf5cb2a | 46 | |
richardparker | 0:839ecbf5cb2a | 47 | // Header incorrect. |
richardparker | 0:839ecbf5cb2a | 48 | return false; |
richardparker | 0:839ecbf5cb2a | 49 | } |
richardparker | 0:839ecbf5cb2a | 50 | |
richardparker | 0:839ecbf5cb2a | 51 | // Now read the bmp file size. |
richardparker | 0:839ecbf5cb2a | 52 | fread(&bufint, 1, 4, fp); |
richardparker | 0:839ecbf5cb2a | 53 | |
richardparker | 0:839ecbf5cb2a | 54 | // Now read the two creator values and throw away. |
richardparker | 0:839ecbf5cb2a | 55 | fread(&bufint, 1, 2, fp); |
richardparker | 0:839ecbf5cb2a | 56 | fread(&bufint, 1, 2, fp); |
richardparker | 0:839ecbf5cb2a | 57 | |
richardparker | 0:839ecbf5cb2a | 58 | // Now read the offset for the bitmap data. |
richardparker | 0:839ecbf5cb2a | 59 | fread(&bufint, 1, 4, fp); |
richardparker | 0:839ecbf5cb2a | 60 | offset = bufint; |
richardparker | 0:839ecbf5cb2a | 61 | |
richardparker | 0:839ecbf5cb2a | 62 | // Retrieve the header. |
richardparker | 0:839ecbf5cb2a | 63 | fread(&header, sizeof(EABMPHeader), 1, fp); |
richardparker | 0:839ecbf5cb2a | 64 | |
richardparker | 0:839ecbf5cb2a | 65 | // Make sure the bits per pixel is 16 and compression type is bit fields. |
richardparker | 0:839ecbf5cb2a | 66 | if ((header.bitsPerPixel != 16) || (header.compressionType != 3)) |
richardparker | 0:839ecbf5cb2a | 67 | { |
richardparker | 0:839ecbf5cb2a | 68 | // Clean up file handle. |
richardparker | 0:839ecbf5cb2a | 69 | fclose(fp); |
richardparker | 0:839ecbf5cb2a | 70 | |
richardparker | 0:839ecbf5cb2a | 71 | // Header incorrect. |
richardparker | 0:839ecbf5cb2a | 72 | return false; |
richardparker | 0:839ecbf5cb2a | 73 | } |
richardparker | 0:839ecbf5cb2a | 74 | |
richardparker | 0:839ecbf5cb2a | 75 | // Set the values for later. |
richardparker | 0:839ecbf5cb2a | 76 | _dataOffset = offset; |
richardparker | 0:839ecbf5cb2a | 77 | setWidth(header.width); |
richardparker | 0:839ecbf5cb2a | 78 | setHeight(header.height); |
richardparker | 0:839ecbf5cb2a | 79 | |
richardparker | 0:839ecbf5cb2a | 80 | // Close the file. |
richardparker | 0:839ecbf5cb2a | 81 | fclose(fp); |
richardparker | 0:839ecbf5cb2a | 82 | |
richardparker | 0:839ecbf5cb2a | 83 | return true; |
richardparker | 0:839ecbf5cb2a | 84 | } |
richardparker | 0:839ecbf5cb2a | 85 | |
richardparker | 0:839ecbf5cb2a | 86 | bool EAImage::load(const char* path) |
richardparker | 0:839ecbf5cb2a | 87 | { |
richardparker | 0:839ecbf5cb2a | 88 | if (path == NULL) |
richardparker | 0:839ecbf5cb2a | 89 | { |
richardparker | 0:839ecbf5cb2a | 90 | // Invalid path passed in. |
richardparker | 0:839ecbf5cb2a | 91 | return false; |
richardparker | 0:839ecbf5cb2a | 92 | } |
richardparker | 0:839ecbf5cb2a | 93 | |
richardparker | 0:839ecbf5cb2a | 94 | if (_loadHeader(path) == false) |
richardparker | 0:839ecbf5cb2a | 95 | { |
richardparker | 0:839ecbf5cb2a | 96 | return false; |
richardparker | 0:839ecbf5cb2a | 97 | } |
richardparker | 0:839ecbf5cb2a | 98 | |
richardparker | 0:839ecbf5cb2a | 99 | int pathLen = strlen(path); |
richardparker | 0:839ecbf5cb2a | 100 | |
richardparker | 0:839ecbf5cb2a | 101 | // If already loaded an image then clear to load the new one. |
richardparker | 0:839ecbf5cb2a | 102 | if (_path != NULL) |
richardparker | 0:839ecbf5cb2a | 103 | { |
richardparker | 0:839ecbf5cb2a | 104 | delete[] _path; |
richardparker | 0:839ecbf5cb2a | 105 | _path = NULL; |
richardparker | 0:839ecbf5cb2a | 106 | } |
richardparker | 0:839ecbf5cb2a | 107 | |
richardparker | 0:839ecbf5cb2a | 108 | // Now allocate enough space to hold path. Note +1 for null character. |
richardparker | 0:839ecbf5cb2a | 109 | _path = new char[pathLen+1]; |
richardparker | 0:839ecbf5cb2a | 110 | |
richardparker | 0:839ecbf5cb2a | 111 | // Now copy over passed in path to path variable. |
richardparker | 0:839ecbf5cb2a | 112 | strcpy(_path, path); |
richardparker | 0:839ecbf5cb2a | 113 | |
richardparker | 0:839ecbf5cb2a | 114 | // Image loaded successfully. |
richardparker | 0:839ecbf5cb2a | 115 | return true; |
richardparker | 0:839ecbf5cb2a | 116 | } |
richardparker | 0:839ecbf5cb2a | 117 | |
richardparker | 0:839ecbf5cb2a | 118 | void EAImage::paint(EALCD& lcd) |
richardparker | 0:839ecbf5cb2a | 119 | { |
richardparker | 0:839ecbf5cb2a | 120 | paint(lcd, 0, 0, width(), height()); |
richardparker | 0:839ecbf5cb2a | 121 | } |
richardparker | 0:839ecbf5cb2a | 122 | |
richardparker | 0:839ecbf5cb2a | 123 | void EAImage::paint(EALCD& lcd, unsigned int x, unsigned int y, unsigned int w, unsigned int h) |
richardparker | 0:839ecbf5cb2a | 124 | { |
richardparker | 0:839ecbf5cb2a | 125 | if (isValid() == false) |
richardparker | 0:839ecbf5cb2a | 126 | { |
richardparker | 0:839ecbf5cb2a | 127 | return; |
richardparker | 0:839ecbf5cb2a | 128 | } |
richardparker | 0:839ecbf5cb2a | 129 | |
richardparker | 0:839ecbf5cb2a | 130 | // Don't allow draw out of range. |
richardparker | 0:839ecbf5cb2a | 131 | if (x + w > width()) |
richardparker | 0:839ecbf5cb2a | 132 | { |
richardparker | 0:839ecbf5cb2a | 133 | return; |
richardparker | 0:839ecbf5cb2a | 134 | } |
richardparker | 0:839ecbf5cb2a | 135 | |
richardparker | 0:839ecbf5cb2a | 136 | if (y + h > height()) |
richardparker | 0:839ecbf5cb2a | 137 | { |
richardparker | 0:839ecbf5cb2a | 138 | return; |
richardparker | 0:839ecbf5cb2a | 139 | } |
richardparker | 0:839ecbf5cb2a | 140 | |
richardparker | 0:839ecbf5cb2a | 141 | // Buffer to hold load one line at a time. |
richardparker | 0:839ecbf5cb2a | 142 | int pixelsInLine = width() + (width() % 2); |
richardparker | 0:839ecbf5cb2a | 143 | unsigned short buffer[pixelsInLine]; |
richardparker | 0:839ecbf5cb2a | 144 | int xD = 0; |
richardparker | 0:839ecbf5cb2a | 145 | int yD = 0; |
richardparker | 0:839ecbf5cb2a | 146 | |
richardparker | 0:839ecbf5cb2a | 147 | // Try and open the file, skip straight to the data. |
richardparker | 0:839ecbf5cb2a | 148 | FILE* fp = fopen(_path, "r"); |
richardparker | 0:839ecbf5cb2a | 149 | if (fp == NULL) |
richardparker | 0:839ecbf5cb2a | 150 | { |
richardparker | 0:839ecbf5cb2a | 151 | return; |
richardparker | 0:839ecbf5cb2a | 152 | } |
richardparker | 0:839ecbf5cb2a | 153 | |
richardparker | 0:839ecbf5cb2a | 154 | // Skip the header and size. |
richardparker | 0:839ecbf5cb2a | 155 | fseek(fp, _dataOffset, SEEK_SET); |
richardparker | 0:839ecbf5cb2a | 156 | |
richardparker | 0:839ecbf5cb2a | 157 | // Prepare the lcd for drawing. |
richardparker | 0:839ecbf5cb2a | 158 | lcd._window(this->x(), this->y(), w, h); |
richardparker | 0:839ecbf5cb2a | 159 | lcd._moveTo(this->x(), this->y()); |
richardparker | 0:839ecbf5cb2a | 160 | |
richardparker | 0:839ecbf5cb2a | 161 | // Move in the file to the first pixel in the window. |
richardparker | 0:839ecbf5cb2a | 162 | fseek(fp, (y*pixelsInLine*2)+(x*2), SEEK_CUR); |
richardparker | 0:839ecbf5cb2a | 163 | |
richardparker | 0:839ecbf5cb2a | 164 | // Now read the data. |
richardparker | 0:839ecbf5cb2a | 165 | while (!feof(fp)) |
richardparker | 0:839ecbf5cb2a | 166 | { |
richardparker | 0:839ecbf5cb2a | 167 | int sizeRead = fread(&buffer, 2, pixelsInLine, fp); |
richardparker | 0:839ecbf5cb2a | 168 | |
richardparker | 0:839ecbf5cb2a | 169 | for (int i = 0; i < sizeRead; i++) |
richardparker | 0:839ecbf5cb2a | 170 | { |
richardparker | 0:839ecbf5cb2a | 171 | lcd._writeToDisplay(buffer[i]); |
richardparker | 0:839ecbf5cb2a | 172 | |
richardparker | 0:839ecbf5cb2a | 173 | // Keep count of current x value. |
richardparker | 0:839ecbf5cb2a | 174 | xD++; |
richardparker | 0:839ecbf5cb2a | 175 | if (xD == w) |
richardparker | 0:839ecbf5cb2a | 176 | { |
richardparker | 0:839ecbf5cb2a | 177 | xD = 0; |
richardparker | 0:839ecbf5cb2a | 178 | break; |
richardparker | 0:839ecbf5cb2a | 179 | } |
richardparker | 0:839ecbf5cb2a | 180 | } |
richardparker | 0:839ecbf5cb2a | 181 | |
richardparker | 0:839ecbf5cb2a | 182 | // Keep count of curernt y value. |
richardparker | 0:839ecbf5cb2a | 183 | yD++; |
richardparker | 0:839ecbf5cb2a | 184 | if (yD == h) |
richardparker | 0:839ecbf5cb2a | 185 | { |
richardparker | 0:839ecbf5cb2a | 186 | break; |
richardparker | 0:839ecbf5cb2a | 187 | } |
richardparker | 0:839ecbf5cb2a | 188 | } |
richardparker | 0:839ecbf5cb2a | 189 | |
richardparker | 0:839ecbf5cb2a | 190 | // Close the file and release handle. |
richardparker | 0:839ecbf5cb2a | 191 | fclose(fp); |
richardparker | 0:839ecbf5cb2a | 192 | |
richardparker | 0:839ecbf5cb2a | 193 | } |
richardparker | 0:839ecbf5cb2a | 194 | |
richardparker | 0:839ecbf5cb2a | 195 |