36 static uint32_t moduleInit = 0;
37 static uint32_t fileReset = 0;
38 static uint32_t paletteRead = 0;
39 static uint32_t bytesInImage = 0;
40 static uint32_t dataIdx = 0;
43 typedef struct __BMP_RleInfo
50 uint8_t pixelsRemaining;
58 EMSTATUS (*fpReadData)(uint8_t buffer[], uint32_t bufLength, uint32_t bytesToRead);
63 static EMSTATUS BMP_readRawData8bit(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength);
64 static EMSTATUS BMP_readRawData24bit(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength);
65 static EMSTATUS BMP_readRawDataRLE8(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength);
66 static EMSTATUS BMP_readPaddingBytes(uint8_t paddingBytes);
67 static EMSTATUS BMP_readRleData(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength);
68 static EMSTATUS BMP_readRgbDataRLE8(uint8_t buffer[], uint32_t bufLength, uint32_t *pixelsRead);
99 EMSTATUS
BMP_init(uint8_t *palette, uint32_t paletteSize, EMSTATUS (*fp)(uint8_t buffer[], uint32_t bufLength, uint32_t bytesToRead))
107 bmpPalette.
data = palette;
108 bmpPalette.
size = paletteSize;
147 if (bmpHeader.
magic != 0x4D42)
149 if (bmpHeader.
magic == 0x424D)
197 status = fpReadData(bmpPalette.
data, bmpPalette.
size, pSize);
206 for (i = 0; i < pSize; i += 4)
208 swap = bmpPalette.
data[i];
210 bmpPalette.
data[i] = bmpPalette.
data[i + 2];
212 bmpPalette.
data[i + 2] = swap;
221 rleInfo.mode = MODE_RLE;
222 rleInfo.isPadding = 0;
223 rleInfo.pixelsRemaining = 0;
224 rleInfo.pixelIdx = 0;
266 uint32_t bytesLeftInBuffer = bufLength - (bufLength % 3);
267 uint32_t bytesToRead;
269 uint32_t bufferIdx = 0;
284 status = BMP_readRgbDataRLE8(buffer, bufLength, pixelsRead);
285 if (status !=
BMP_OK)
return status;
292 while (bytesLeftInBuffer > 0 && dataType.
endOfRow == 0)
298 if (bytesLeftInBuffer < bytesToRead * 3)
300 bytesToRead = bytesLeftInBuffer / 3;
304 status = BMP_readRawData8bit(&dataType, localCache, bytesToRead);
305 if (status !=
BMP_OK)
return status;
308 for (i = 0; i < dataType.
size; ++i)
311 buffer[ bufferIdx ] = bmpPalette.
data[ 4 * localCache[i] ];
313 buffer[ bufferIdx + 1 ] = bmpPalette.
data[ 4 * localCache[i] + 1 ];
315 buffer[ bufferIdx + 2 ] = bmpPalette.
data[ 4 * localCache[i] + 2 ];
320 *pixelsRead += dataType.
size;
321 bytesLeftInBuffer -= dataType.
size * 3;
327 uint8_t paddingBytes = bytesPerRow - bmpHeader.
width;
329 status = BMP_readPaddingBytes(paddingBytes);
338 *pixelsRead = dataType.
size / 3;
359 static EMSTATUS BMP_readRgbDataRLE8(uint8_t buffer[], uint32_t bufLength, uint32_t *pixelsRead)
364 uint32_t bufferIdx = 0;
365 uint32_t bytesLeftInBuffer = bufLength - (bufLength % 3);
366 uint32_t bytesToRead;
369 while (bytesLeftInBuffer > 0 && dataType.
endOfRow == 0)
371 if (rleInfo.mode == MODE_RLE)
376 while (rleInfo.pixelsRemaining > 0 && bytesLeftInBuffer > 0)
379 buffer[ bufferIdx ] = bmpPalette.
data[ 4 * rleInfo.pixelIdx ];
381 buffer[ bufferIdx + 1 ] = bmpPalette.
data[ 4 * rleInfo.pixelIdx + 1 ];
383 buffer[ bufferIdx + 2 ] = bmpPalette.
data[ 4 * rleInfo.pixelIdx + 2 ];
385 rleInfo.pixelsRemaining -= 1;
386 bytesLeftInBuffer -= 3;
392 if (rleInfo.pixelsRemaining == 0)
396 if (status !=
BMP_OK)
return status;
399 if (localCache[0] > 0)
402 rleInfo.pixelsRemaining = localCache[0];
403 rleInfo.pixelIdx = localCache[ 1 ];
408 if (rleInfo.mode == MODE_8BIT)
413 bytesToRead = rleInfo.pixelsRemaining;
415 if (bytesToRead * 3 > bytesLeftInBuffer)
417 bytesToRead = bytesLeftInBuffer / 3;
433 dataIdx += bytesToRead;
436 for (i = 0; i < bytesToRead; ++i)
439 buffer[ bufferIdx ] = bmpPalette.
data[ 4 * localCache[i] ];
441 buffer[ bufferIdx + 1 ] = bmpPalette.
data[ 4 * localCache[i] + 1 ];
443 buffer[ bufferIdx + 2 ] = bmpPalette.
data[ 4 * localCache[i] + 2 ];
446 bytesLeftInBuffer -= 3;
449 *pixelsRead += bytesToRead;
450 rleInfo.pixelsRemaining -= bytesToRead;
452 if (rleInfo.pixelsRemaining == 0)
455 rleInfo.mode = MODE_RLE;
458 if (rleInfo.isPadding == 1)
461 if (status !=
BMP_OK)
return status;
468 if (status !=
BMP_OK)
return status;
471 if (localCache[0] > 0)
474 rleInfo.pixelsRemaining = localCache[0];
475 rleInfo.pixelIdx = localCache[1];
498 static EMSTATUS BMP_readRawData8bit(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength)
505 uint32_t bytesToRead;
514 bytesToRead = bmpHeader.
width - dataIdx % bytesPerRow;
518 if (bufLength < bytesToRead)
520 bytesToRead = bufLength;
525 status = fpReadData(buffer, bufLength, bytesToRead);
531 dataIdx += bytesToRead;
532 dataType->
size = bytesToRead;
551 static EMSTATUS BMP_readRawData24bit(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength)
559 uint32_t bytesLeftInBuffer = bufLength - (bufLength % 3);
560 uint32_t bytesToRead;
569 bytesToRead = bmpHeader.
width * 3 - dataIdx % bytesPerRow;
572 if (bytesToRead > bytesLeftInBuffer)
574 bytesToRead = bytesLeftInBuffer;
579 status = fpReadData(buffer, bufLength, bytesToRead);
585 dataIdx += bytesToRead;
586 dataType->
size = bytesToRead;
589 for (i = 0; i < bytesToRead; i += 3)
593 buffer[ i ] = buffer[i + 2];
595 buffer[ i + 2 ] = swap;
598 bytesLeftInBuffer -= bytesToRead;
617 static EMSTATUS BMP_readRawDataRLE8(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength)
621 uint32_t bufferIdx = 0;
625 if (rleInfo.mode == MODE_RLE)
632 if (bufLength % 2 == 1) bufLength--;
635 if (rleInfo.pixelsRemaining > 0)
637 buffer[ bufferIdx ] = rleInfo.pixelsRemaining;
638 buffer[ bufferIdx + 1 ] = rleInfo.pixelIdx;
644 while (rleInfo.mode == MODE_RLE && bufferIdx < bufLength && dataType->endOfRow == 0)
648 if (status !=
BMP_OK)
return status;
651 if (localCache[0] > 0)
654 buffer[ bufferIdx ] = localCache[0];
655 buffer[ bufferIdx + 1 ] = localCache[1];
663 if (rleInfo.mode == MODE_8BIT && bufferIdx == 0)
668 uint32_t bytesToRead = rleInfo.pixelsRemaining;
670 if (bytesToRead > bufLength)
672 bytesToRead = bufLength;
676 status = fpReadData(buffer, bufLength, bytesToRead);
683 rleInfo.pixelsRemaining -= bytesToRead;
684 dataIdx += bytesToRead;
685 dataType->
size = bytesToRead;
687 if (rleInfo.pixelsRemaining == 0)
690 rleInfo.mode = MODE_RLE;
693 if (rleInfo.isPadding == 1)
696 if (status !=
BMP_OK)
return status;
704 if (rleInfo.mode == MODE_RLE && rleInfo.pixelsRemaining == 0 && dataType->
endOfRow == 0)
708 if (status !=
BMP_OK)
return status;
711 if (localCache[0] > 0)
714 rleInfo.pixelsRemaining = localCache[0];
715 rleInfo.pixelIdx = localCache[1];
732 static EMSTATUS BMP_readPaddingBytes(uint8_t paddingBytes)
734 if (paddingBytes > 0)
743 dataIdx += paddingBytes;
766 static EMSTATUS BMP_readRleData(
BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength)
772 rleInfo.mode = MODE_RLE;
773 rleInfo.pixelsRemaining = 0;
774 rleInfo.pixelIdx = 0;
775 rleInfo.isPadding = 0;
779 if (status !=
BMP_OK)
return status;
783 if (dataIdx >= bytesInImage)
790 if (localCache[0] == 0)
793 if (localCache[1] == 0)
798 else if (localCache[1] == 1)
804 else if (localCache[1] == 2)
809 if (status !=
BMP_OK)
return status;
814 else if (localCache[1] > 2)
817 rleInfo.mode = MODE_8BIT;
818 rleInfo.pixelsRemaining = localCache[1];
820 if (rleInfo.pixelsRemaining % 2 == 1) rleInfo.isPadding = 1;
854 uint8_t paddingBytes;
875 status = BMP_readRawData24bit(dataType, buffer, bufLength);
881 paddingBytes = bytesPerRow - bmpHeader.
width * 3;
883 status = BMP_readPaddingBytes(paddingBytes);
884 if (status !=
BMP_OK)
return status;
896 status = BMP_readRawData8bit(dataType, buffer, bufLength);
902 paddingBytes = bytesPerRow - bmpHeader.
width;
904 status = BMP_readPaddingBytes(paddingBytes);
905 if (status !=
BMP_OK)
return status;
911 status = BMP_readRawDataRLE8(dataType, buffer, bufLength);
927 if (moduleInit == 0 || fileReset == 0)
return -1;
929 return bmpHeader.
width;
941 if (moduleInit == 0 || fileReset == 0)
return -1;
955 if (moduleInit == 0 || fileReset == 0)
return -1;
973 if (moduleInit == 0 || fileReset == 0)
return -1;
987 if (moduleInit == 0 || fileReset == 0)
return -1;
1001 if (moduleInit == 0 || fileReset == 0)
return -1;
1015 if (moduleInit == 0 || fileReset == 0)
return -1;
#define BMP_ERROR_INVALID_ARGUMENT
EMSTATUS BMP_reset()
Makes the module ready for new bmp file. Reads in header from file, and checks if the provided bmp fi...
#define BMP_ERROR_MODULE_NOT_INITIALIZED
#define BMP_ERROR_FILE_NOT_SUPPORTED
#define BMP_ERROR_PALETTE_NOT_READ
#define BMP_ERROR_FILE_NOT_RESET
int32_t BMP_getHeight()
Get height of BMP image in pixels.
BMP palette structure to hold palette pointer and size.
#define BMP_LOCAL_CACHE_SIZE
#define BMP_ERROR_END_OF_FILE
int32_t BMP_getWidth()
Get width of BMP image in pixels.
int32_t BMP_getCompressionType()
Get compression type.
int32_t BMP_getFileSize()
Get the fileSize in bytes.
#define BMP_ERROR_BUFFER_TOO_SMALL
int16_t BMP_getBitsPerPixel()
Get color depth (bits per pixel)
#define BMP_ERROR_ENDIAN_MISMATCH
#define BMP_ERROR_FILE_INVALID
EMSTATUS BMP_readRawData(BMP_DataType *dataType, uint8_t buffer[], uint32_t bufLength)
Fills buffer with raw data from BMP file.
#define BMP_ERROR_INVALID_PALETTE_SIZE
EMSTATUS BMP_init(uint8_t *palette, uint32_t paletteSize, EMSTATUS(*fp)(uint8_t buffer[], uint32_t bufLength, uint32_t bytesToRead))
Initializes BMP Module.
BMP Data type structure to hold information about the bmp data returned.
#define BMP_ERROR_HEADER_SIZE_MISMATCH
int32_t BMP_getImageDataSize()
Get imageDataSize in bytes.
int32_t BMP_getDataOffset()
Get the offset, i.e. starting address, of the byte where the bitmap data can be found.
EMSTATUS BMP_readRgbData(uint8_t buffer[], uint32_t bufLength, uint32_t *pixelsRead)
Reads in data from BMP file and fills buffer with RGB values. This function terminates either when th...
#define BMP_LOCAL_CACHE_LIMIT