Richard Parker / EALCD
Committer:
richardparker
Date:
Thu Feb 11 12:21:18 2010 +0000
Revision:
0:839ecbf5cb2a
Child:
1:f04bcaea1d60

        

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 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