clang, remove travis, add actions, bump
This commit is contained in:
parent
60d96d6812
commit
70152a185d
10 changed files with 421 additions and 331 deletions
46
.github/ISSUE_TEMPLATE.md
vendored
Normal file
46
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
32
.github/workflows/githubci.yml
vendored
Normal file
32
.github/workflows/githubci.yml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
name: Arduino Library CI
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: adafruit/ci-arduino
|
||||
path: ci
|
||||
|
||||
- name: pre-install
|
||||
run: bash ci/actions_install.sh
|
||||
|
||||
- name: test platforms
|
||||
run: python3 ci/build_platform.py main_platforms arcada_platforms
|
||||
|
||||
- name: clang
|
||||
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
||||
|
||||
- name: doxygen
|
||||
env:
|
||||
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
|
||||
PRETTYNAME : "Adafruit ImageReader Library"
|
||||
run: bash ci/doxy_gen_and_deploy.sh
|
||||
33
.travis.yml
33
.travis.yml
|
|
@ -1,33 +0,0 @@
|
|||
language: c
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- ~/arduino_ide
|
||||
- ~/.arduino15/packages/
|
||||
|
||||
git:
|
||||
depth: false
|
||||
quiet: true
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
|
||||
env:
|
||||
global:
|
||||
- PRETTYNAME="Adafruit ImageLoader Arduino Library"
|
||||
|
||||
before_install:
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
|
||||
|
||||
script:
|
||||
- build_cplay_platforms
|
||||
- build_main_platforms
|
||||
|
||||
# Generate and deploy documentation
|
||||
after_success:
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
|
||||
|
|
@ -49,9 +49,9 @@
|
|||
// on screen or image size.)
|
||||
|
||||
#ifdef __AVR__
|
||||
#define BUFPIXELS 24 ///< 24 * 5 = 120 bytes
|
||||
#define BUFPIXELS 24 ///< 24 * 5 = 120 bytes
|
||||
#else
|
||||
#define BUFPIXELS 200 ///< 200 * 5 = 1000 bytes
|
||||
#define BUFPIXELS 200 ///< 200 * 5 = 1000 bytes
|
||||
#endif
|
||||
|
||||
// ADAFRUIT_IMAGE CLASS ****************************************************
|
||||
|
|
@ -64,8 +64,8 @@
|
|||
@brief Constructor.
|
||||
@return 'Empty' Adafruit_Image object.
|
||||
*/
|
||||
Adafruit_Image::Adafruit_Image(void) : mask(NULL), palette(NULL),
|
||||
format(IMAGE_NONE) {
|
||||
Adafruit_Image::Adafruit_Image(void)
|
||||
: mask(NULL), palette(NULL), format(IMAGE_NONE) {
|
||||
canvas.canvas1 = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -73,9 +73,7 @@ Adafruit_Image::Adafruit_Image(void) : mask(NULL), palette(NULL),
|
|||
@brief Destructor.
|
||||
@return None (void).
|
||||
*/
|
||||
Adafruit_Image::~Adafruit_Image(void) {
|
||||
dealloc();
|
||||
}
|
||||
Adafruit_Image::~Adafruit_Image(void) { dealloc(); }
|
||||
|
||||
/*!
|
||||
@brief Deallocates memory associated with Adafruit_Image object
|
||||
|
|
@ -83,27 +81,27 @@ Adafruit_Image::~Adafruit_Image(void) {
|
|||
@return None (void).
|
||||
*/
|
||||
void Adafruit_Image::dealloc(void) {
|
||||
if(format == IMAGE_1 ) {
|
||||
if(canvas.canvas1) {
|
||||
if (format == IMAGE_1) {
|
||||
if (canvas.canvas1) {
|
||||
delete canvas.canvas1;
|
||||
canvas.canvas1 = NULL;
|
||||
}
|
||||
} else if(format == IMAGE_8 ) {
|
||||
if(canvas.canvas8) {
|
||||
} else if (format == IMAGE_8) {
|
||||
if (canvas.canvas8) {
|
||||
delete canvas.canvas8;
|
||||
canvas.canvas8 = NULL;
|
||||
}
|
||||
} else if(format == IMAGE_16) {
|
||||
if(canvas.canvas16) {
|
||||
} else if (format == IMAGE_16) {
|
||||
if (canvas.canvas16) {
|
||||
delete canvas.canvas16;
|
||||
canvas.canvas16 = NULL;
|
||||
}
|
||||
}
|
||||
if(mask) {
|
||||
if (mask) {
|
||||
delete mask;
|
||||
mask = NULL;
|
||||
}
|
||||
if(palette) {
|
||||
if (palette) {
|
||||
delete[] palette;
|
||||
palette = NULL;
|
||||
}
|
||||
|
|
@ -115,10 +113,13 @@ void Adafruit_Image::dealloc(void) {
|
|||
@return Width in pixels, or 0 if no image loaded.
|
||||
*/
|
||||
int16_t Adafruit_Image::width(void) const {
|
||||
if(format != IMAGE_NONE) { // Image allocated?
|
||||
if( format == IMAGE_1 ) return canvas.canvas1->width();
|
||||
else if(format == IMAGE_8 ) return canvas.canvas8->width();
|
||||
else if(format == IMAGE_16) return canvas.canvas16->width();
|
||||
if (format != IMAGE_NONE) { // Image allocated?
|
||||
if (format == IMAGE_1)
|
||||
return canvas.canvas1->width();
|
||||
else if (format == IMAGE_8)
|
||||
return canvas.canvas8->width();
|
||||
else if (format == IMAGE_16)
|
||||
return canvas.canvas16->width();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -128,10 +129,13 @@ int16_t Adafruit_Image::width(void) const {
|
|||
@return Height in pixels, or 0 if no image loaded.
|
||||
*/
|
||||
int16_t Adafruit_Image::height(void) const {
|
||||
if(format != IMAGE_NONE) { // Image allocated?
|
||||
if( format == IMAGE_1 ) return canvas.canvas1->height();
|
||||
else if(format == IMAGE_8 ) return canvas.canvas8->height();
|
||||
else if(format == IMAGE_16) return canvas.canvas16->height();
|
||||
if (format != IMAGE_NONE) { // Image allocated?
|
||||
if (format == IMAGE_1)
|
||||
return canvas.canvas1->height();
|
||||
else if (format == IMAGE_8)
|
||||
return canvas.canvas8->height();
|
||||
else if (format == IMAGE_16)
|
||||
return canvas.canvas16->height();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -153,10 +157,13 @@ int16_t Adafruit_Image::height(void) const {
|
|||
for a lot of mayhem here if used wrong.
|
||||
*/
|
||||
void *Adafruit_Image::getCanvas(void) const {
|
||||
if(format != IMAGE_NONE) { // Image allocated?
|
||||
if( format == IMAGE_1 ) return (void *)canvas.canvas1;
|
||||
else if(format == IMAGE_8 ) return (void *)canvas.canvas8;
|
||||
else if(format == IMAGE_16) return (void *)canvas.canvas16;
|
||||
if (format != IMAGE_NONE) { // Image allocated?
|
||||
if (format == IMAGE_1)
|
||||
return (void *)canvas.canvas1;
|
||||
else if (format == IMAGE_8)
|
||||
return (void *)canvas.canvas8;
|
||||
else if (format == IMAGE_16)
|
||||
return (void *)canvas.canvas16;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -174,20 +181,19 @@ void *Adafruit_Image::getCanvas(void) const {
|
|||
@return None (void).
|
||||
*/
|
||||
void Adafruit_Image::draw(Adafruit_SPITFT &tft, int16_t x, int16_t y) {
|
||||
if(format == IMAGE_1 ) {
|
||||
if (format == IMAGE_1) {
|
||||
uint16_t foreground, background;
|
||||
if(palette) {
|
||||
if (palette) {
|
||||
foreground = palette[1];
|
||||
background = palette[0];
|
||||
} else {
|
||||
foreground = 0xFFFF;
|
||||
background = 0x0000;
|
||||
}
|
||||
tft.drawBitmap(x, y, canvas.canvas1->getBuffer(),
|
||||
canvas.canvas1->width(), canvas.canvas1->height(),
|
||||
foreground, background);
|
||||
} else if(format == IMAGE_8 ) {
|
||||
} else if(format == IMAGE_16) {
|
||||
tft.drawBitmap(x, y, canvas.canvas1->getBuffer(), canvas.canvas1->width(),
|
||||
canvas.canvas1->height(), foreground, background);
|
||||
} else if (format == IMAGE_8) {
|
||||
} else if (format == IMAGE_16) {
|
||||
tft.drawRGBBitmap(x, y, canvas.canvas16->getBuffer(),
|
||||
canvas.canvas16->width(), canvas.canvas16->height());
|
||||
}
|
||||
|
|
@ -208,16 +214,15 @@ void Adafruit_Image::draw(Adafruit_SPITFT &tft, int16_t x, int16_t y) {
|
|||
often be in pre-setup() declaration, but DOES need initializing
|
||||
before any of the image loading or size functions are called!
|
||||
*/
|
||||
Adafruit_ImageReader::Adafruit_ImageReader(FatFileSystem &fs) {
|
||||
filesys = &fs;
|
||||
}
|
||||
Adafruit_ImageReader::Adafruit_ImageReader(FatFileSystem &fs) { filesys = &fs; }
|
||||
|
||||
/*!
|
||||
@brief Destructor.
|
||||
@return None (void).
|
||||
*/
|
||||
Adafruit_ImageReader::~Adafruit_ImageReader(void) {
|
||||
if(file) file.close();
|
||||
if (file)
|
||||
file.close();
|
||||
// filesystem is left as-is
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +247,8 @@ Adafruit_ImageReader::~Adafruit_ImageReader(void) {
|
|||
completion, other values on failure).
|
||||
*/
|
||||
ImageReturnCode Adafruit_ImageReader::drawBMP(char *filename,
|
||||
Adafruit_SPITFT &tft, int16_t x, int16_t y, boolean transact) {
|
||||
Adafruit_SPITFT &tft, int16_t x,
|
||||
int16_t y, boolean transact) {
|
||||
uint16_t tftbuf[BUFPIXELS]; // Temp space for buffering TFT data
|
||||
// Call core BMP-reading function, passing address to TFT object,
|
||||
// TFT working buffer, and X & Y position of top-left corner (image
|
||||
|
|
@ -264,8 +270,8 @@ ImageReturnCode Adafruit_ImageReader::drawBMP(char *filename,
|
|||
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
||||
completion, other values on failure).
|
||||
*/
|
||||
ImageReturnCode Adafruit_ImageReader::loadBMP(
|
||||
char *filename, Adafruit_Image &img) {
|
||||
ImageReturnCode Adafruit_ImageReader::loadBMP(char *filename,
|
||||
Adafruit_Image &img) {
|
||||
// Call core BMP-reading function. TFT and working buffer are NULL
|
||||
// (unused and allocated in function, respectively), X & Y position are
|
||||
// always 0 because full image is loaded (RAM permitting). Adafruit_Image
|
||||
|
|
@ -320,8 +326,8 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
uint32_t colors = 0; // Number of colors in palette
|
||||
uint16_t *quantized = NULL; // 16-bit 5/6/5 color palette
|
||||
uint32_t rowSize; // >bmpWidth if scanline padding
|
||||
uint8_t sdbuf[3*BUFPIXELS]; // BMP read buf (R+G+B/pixel)
|
||||
#if ((3*BUFPIXELS) <= 255)
|
||||
uint8_t sdbuf[3 * BUFPIXELS]; // BMP read buf (R+G+B/pixel)
|
||||
#if ((3 * BUFPIXELS) <= 255)
|
||||
uint8_t srcidx = sizeof sdbuf; // Current position in sdbuf
|
||||
#else
|
||||
uint16_t srcidx = sizeof sdbuf;
|
||||
|
|
@ -331,7 +337,7 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
boolean flip = true; // BMP is stored bottom-to-top
|
||||
uint32_t bmpPos = 0; // Next pixel position in file
|
||||
int loadWidth, loadHeight, // Region being loaded (clipped)
|
||||
loadX , loadY; // "
|
||||
loadX, loadY; // "
|
||||
int row, col; // Current pixel pos.
|
||||
uint8_t r, g, b; // Current pixel color
|
||||
uint8_t bitIn = 0; // Bit number for 1-bit data in
|
||||
|
|
@ -339,22 +345,23 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
|
||||
// If an Adafruit_Image object is passed and currently contains anything,
|
||||
// free its contents as it's about to be overwritten with new stuff.
|
||||
if(img) img->dealloc();
|
||||
if (img)
|
||||
img->dealloc();
|
||||
|
||||
// If BMP is being drawn off the right or bottom edge of the screen,
|
||||
// nothing to do here. NOT an error, just a trivial clip operation.
|
||||
if(tft && ((x >= tft->width()) || (y >= tft->height())))
|
||||
if (tft && ((x >= tft->width()) || (y >= tft->height())))
|
||||
return IMAGE_SUCCESS;
|
||||
|
||||
// Open requested file on SD card
|
||||
if(!(file = filesys->open(filename, FILE_READ))) {
|
||||
if (!(file = filesys->open(filename, FILE_READ))) {
|
||||
return IMAGE_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Parse BMP header. 0x4D42 (ASCII 'BM') is the Windows BMP signature.
|
||||
// There are other values possible in a .BMP file but these are super
|
||||
// esoteric (e.g. OS/2 struct bitmap array) and NOT supported here!
|
||||
if(readLE16() == 0x4D42) { // BMP signature
|
||||
if (readLE16() == 0x4D42) { // BMP signature
|
||||
(void)readLE32(); // Read & ignore file size
|
||||
(void)readLE32(); // Read & ignore creator bytes
|
||||
offset = readLE32(); // Start of image data
|
||||
|
|
@ -364,14 +371,14 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
bmpHeight = readLE32();
|
||||
// If bmpHeight is negative, image is in top-down order.
|
||||
// This is not canon but has been observed in the wild.
|
||||
if(bmpHeight < 0) {
|
||||
if (bmpHeight < 0) {
|
||||
bmpHeight = -bmpHeight;
|
||||
flip = false;
|
||||
}
|
||||
planes = readLE16();
|
||||
depth = readLE16(); // Bits per pixel
|
||||
// Compression mode is present in later BMP versions (default = none)
|
||||
if(headerSize > 12) {
|
||||
if (headerSize > 12) {
|
||||
compression = readLE32();
|
||||
(void)readLE32(); // Raw bitmap data size; ignore
|
||||
(void)readLE32(); // Horizontal resolution, ignore
|
||||
|
|
@ -380,81 +387,83 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
(void)readLE32(); // Number of colors used (ignore)
|
||||
// File position should now be at start of palette (if present)
|
||||
}
|
||||
if(!colors) colors = 1 << depth;
|
||||
if (!colors)
|
||||
colors = 1 << depth;
|
||||
|
||||
loadWidth = bmpWidth;
|
||||
loadHeight = bmpHeight;
|
||||
loadX = 0;
|
||||
loadY = 0;
|
||||
if(tft) {
|
||||
if (tft) {
|
||||
// Crop area to be loaded (if destination is TFT)
|
||||
if(x < 0) {
|
||||
if (x < 0) {
|
||||
loadX = -x;
|
||||
loadWidth += x;
|
||||
x = 0;
|
||||
}
|
||||
if(y < 0) {
|
||||
if (y < 0) {
|
||||
loadY = -y;
|
||||
loadHeight += y;
|
||||
y = 0;
|
||||
}
|
||||
if((x + loadWidth ) > tft->width()) loadWidth = tft->width() - x;
|
||||
if((y + loadHeight) > tft->height()) loadHeight = tft->height() - y;
|
||||
if ((x + loadWidth) > tft->width())
|
||||
loadWidth = tft->width() - x;
|
||||
if ((y + loadHeight) > tft->height())
|
||||
loadHeight = tft->height() - y;
|
||||
}
|
||||
|
||||
if((planes == 1) && (compression == 0)) { // Only uncompressed is handled
|
||||
if ((planes == 1) && (compression == 0)) { // Only uncompressed is handled
|
||||
|
||||
// BMP rows are padded (if needed) to 4-byte boundary
|
||||
rowSize = ((depth * bmpWidth + 31) / 32) * 4;
|
||||
|
||||
if((depth == 24) || (depth == 1)) { // BGR or 1-bit bitmap format
|
||||
if ((depth == 24) || (depth == 1)) { // BGR or 1-bit bitmap format
|
||||
|
||||
if(img) {
|
||||
if (img) {
|
||||
// Loading to RAM -- allocate GFX 16-bit canvas type
|
||||
status = IMAGE_ERR_MALLOC; // Assume won't fit to start
|
||||
if(depth == 24) {
|
||||
if((img->canvas.canvas16 = new GFXcanvas16(bmpWidth, bmpHeight))) {
|
||||
if (depth == 24) {
|
||||
if ((img->canvas.canvas16 = new GFXcanvas16(bmpWidth, bmpHeight))) {
|
||||
dest = img->canvas.canvas16->getBuffer();
|
||||
}
|
||||
} else {
|
||||
if((img->canvas.canvas1 = new GFXcanvas1(bmpWidth, bmpHeight))) {
|
||||
if ((img->canvas.canvas1 = new GFXcanvas1(bmpWidth, bmpHeight))) {
|
||||
dest1 = img->canvas.canvas1->getBuffer();
|
||||
}
|
||||
}
|
||||
// Future: handle other depths.
|
||||
}
|
||||
|
||||
if(dest || dest1) { // Supported format, alloc OK, etc.
|
||||
if (dest || dest1) { // Supported format, alloc OK, etc.
|
||||
status = IMAGE_SUCCESS;
|
||||
|
||||
if((loadWidth > 0) && (loadHeight > 0)) { // Clip top/left
|
||||
if(tft) {
|
||||
if ((loadWidth > 0) && (loadHeight > 0)) { // Clip top/left
|
||||
if (tft) {
|
||||
tft->startWrite(); // Start SPI (regardless of transact)
|
||||
tft->setAddrWindow(x, y, loadWidth, loadHeight);
|
||||
} else {
|
||||
if(depth == 1) {
|
||||
if (depth == 1) {
|
||||
img->format = IMAGE_1; // Is a GFX 1-bit canvas type
|
||||
} else {
|
||||
img->format = IMAGE_16; // Is a GFX 16-bit canvas type
|
||||
}
|
||||
}
|
||||
|
||||
if((depth >= 16) ||
|
||||
if ((depth >= 16) ||
|
||||
(quantized = (uint16_t *)malloc(colors * sizeof(uint16_t)))) {
|
||||
if(depth < 16) {
|
||||
if (depth < 16) {
|
||||
// Load and quantize color table
|
||||
for(uint16_t c=0; c<colors; c++) {
|
||||
for (uint16_t c = 0; c < colors; c++) {
|
||||
b = file.read();
|
||||
g = file.read();
|
||||
r = file.read();
|
||||
(void)file.read(); // Ignore 4th byte
|
||||
quantized[c] = ((r & 0xF8) << 8) |
|
||||
((g & 0xFC) << 3) |
|
||||
( b >> 3);
|
||||
quantized[c] =
|
||||
((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
for(row=0; row<loadHeight; row++) { // For each scanline...
|
||||
for (row = 0; row < loadHeight; row++) { // For each scanline...
|
||||
|
||||
yield(); // Keep ESP8266 happy
|
||||
|
||||
|
|
@ -464,31 +473,31 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
// padding. Also, the seek only takes place if the file
|
||||
// position actually needs to change (avoids a lot of cluster
|
||||
// math in SD library).
|
||||
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
bmpPos = offset +
|
||||
(bmpHeight - 1 - (row + loadY)) * rowSize;
|
||||
if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
bmpPos = offset + (bmpHeight - 1 - (row + loadY)) * rowSize;
|
||||
else // Bitmap is stored top-to-bottom
|
||||
bmpPos = offset + (row + loadY) * rowSize;
|
||||
if(depth == 24) {
|
||||
if (depth == 24) {
|
||||
bmpPos += loadX * 3;
|
||||
} else {
|
||||
bmpPos += loadX / 8;
|
||||
bitIn = 7 - (loadX & 7);
|
||||
bitOut = 0x80;
|
||||
if(img) destidx = ((bmpWidth + 7) / 8) * row;
|
||||
if (img)
|
||||
destidx = ((bmpWidth + 7) / 8) * row;
|
||||
}
|
||||
if(file.position() != bmpPos) { // Need seek?
|
||||
if(transact) {
|
||||
if (file.position() != bmpPos) { // Need seek?
|
||||
if (transact) {
|
||||
tft->dmaWait();
|
||||
tft->endWrite(); // End TFT SPI transaction
|
||||
}
|
||||
file.seek(bmpPos); // Seek = SD transaction
|
||||
srcidx = sizeof sdbuf; // Force buffer reload
|
||||
}
|
||||
for(col=0; col<loadWidth; col++) { // For each pixel...
|
||||
if(srcidx >= sizeof sdbuf) { // Time to load more?
|
||||
if(tft) { // Drawing to TFT?
|
||||
if(transact) {
|
||||
for (col = 0; col < loadWidth; col++) { // For each pixel...
|
||||
if (srcidx >= sizeof sdbuf) { // Time to load more?
|
||||
if (tft) { // Drawing to TFT?
|
||||
if (transact) {
|
||||
tft->dmaWait();
|
||||
tft->endWrite(); // End TFT SPI transact
|
||||
}
|
||||
|
|
@ -496,9 +505,9 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
// NRF52840 seems to have trouble reading more than 512
|
||||
// bytes across certain boundaries. Workaround for now
|
||||
// is to break the read into smaller chunks...
|
||||
int32_t bytesToGo = sizeof sdbuf,
|
||||
bytesRead = 0, bytesThisPass;
|
||||
while(bytesToGo > 0) {
|
||||
int32_t bytesToGo = sizeof sdbuf, bytesRead = 0,
|
||||
bytesThisPass;
|
||||
while (bytesToGo > 0) {
|
||||
bytesThisPass = min(bytesToGo, 512);
|
||||
file.read(&sdbuf[bytesRead], bytesThisPass);
|
||||
bytesRead += bytesThisPass;
|
||||
|
|
@ -507,13 +516,14 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
#else
|
||||
file.read(sdbuf, sizeof sdbuf); // Load from SD
|
||||
#endif
|
||||
if(transact) tft->startWrite(); // Start TFT SPI transact
|
||||
if(destidx) { // If buffered TFT data
|
||||
if (transact)
|
||||
tft->startWrite(); // Start TFT SPI transact
|
||||
if (destidx) { // If buffered TFT data
|
||||
// Non-blocking writes (DMA) have been temporarily
|
||||
// disabled until this can be rewritten with two
|
||||
// alternating 'dest' buffers (else the nonblocking
|
||||
// data out is overwritten in the dest[] write below).
|
||||
//tft->writePixels(dest, destidx, false); // Write it
|
||||
// tft->writePixels(dest, destidx, false); // Write it
|
||||
tft->writePixels(dest, destidx, true); // Write it
|
||||
destidx = 0; // and reset dest index
|
||||
}
|
||||
|
|
@ -522,42 +532,43 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
} // (destidx never resets)
|
||||
srcidx = 0; // Reset bmp buf index
|
||||
}
|
||||
if(depth == 24) {
|
||||
if (depth == 24) {
|
||||
// Convert each pixel from BMP to 565 format, save in dest
|
||||
b = sdbuf[srcidx++];
|
||||
g = sdbuf[srcidx++];
|
||||
r = sdbuf[srcidx++];
|
||||
dest[destidx++] = ((r & 0xF8) << 8) |
|
||||
((g & 0xFC) << 3) |
|
||||
( b >> 3);
|
||||
dest[destidx++] =
|
||||
((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||
} else {
|
||||
// Extract 1-bit color index
|
||||
uint8_t n = (sdbuf[srcidx] >> bitIn) & 1;
|
||||
if(!bitIn) {
|
||||
if (!bitIn) {
|
||||
srcidx++;
|
||||
bitIn = 7;
|
||||
} else {
|
||||
bitIn--;
|
||||
}
|
||||
if(tft) {
|
||||
if (tft) {
|
||||
// Look up in palette, store in tft dest buf
|
||||
dest[destidx++] = quantized[n];
|
||||
} else {
|
||||
// Store bit in canvas1 buffer (ignore palette)
|
||||
if(n) dest1[destidx] |= bitOut;
|
||||
else dest1[destidx] &= ~bitOut;
|
||||
if (n)
|
||||
dest1[destidx] |= bitOut;
|
||||
else
|
||||
dest1[destidx] &= ~bitOut;
|
||||
bitOut >>= 1;
|
||||
if(!bitOut) {
|
||||
if (!bitOut) {
|
||||
bitOut = 0x80;
|
||||
destidx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end pixel loop
|
||||
if(tft) { // Drawing to TFT?
|
||||
if(destidx) { // Any remainders?
|
||||
if (tft) { // Drawing to TFT?
|
||||
if (destidx) { // Any remainders?
|
||||
// See notes above re: DMA
|
||||
//tft->writePixels(dest, destidx, false); // Write it
|
||||
// tft->writePixels(dest, destidx, false); // Write it
|
||||
tft->writePixels(dest, destidx, true); // Write it
|
||||
destidx = 0; // and reset dest index
|
||||
}
|
||||
|
|
@ -566,9 +577,11 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
}
|
||||
} // end scanline loop
|
||||
|
||||
if(quantized) {
|
||||
if(tft) free(quantized); // Palette no longer needed
|
||||
else img->palette = quantized; // Keep palette with img
|
||||
if (quantized) {
|
||||
if (tft)
|
||||
free(quantized); // Palette no longer needed
|
||||
else
|
||||
img->palette = quantized; // Keep palette with img
|
||||
}
|
||||
} // end depth>24 or quantized malloc OK
|
||||
} // end top/left clip
|
||||
|
|
@ -592,22 +605,25 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
|||
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
||||
completion, other values on failure).
|
||||
*/
|
||||
ImageReturnCode Adafruit_ImageReader::bmpDimensions(
|
||||
char *filename, int32_t *width, int32_t *height) {
|
||||
ImageReturnCode Adafruit_ImageReader::bmpDimensions(char *filename,
|
||||
int32_t *width,
|
||||
int32_t *height) {
|
||||
|
||||
ImageReturnCode status = IMAGE_ERR_FILE_NOT_FOUND; // Guilty until innocent
|
||||
|
||||
if((file = filesys->open(filename, FILE_READ))) { // Open requested file
|
||||
if ((file = filesys->open(filename, FILE_READ))) { // Open requested file
|
||||
status = IMAGE_ERR_FORMAT; // File's there, might not be BMP tho
|
||||
if(readLE16() == 0x4D42) { // BMP signature?
|
||||
if (readLE16() == 0x4D42) { // BMP signature?
|
||||
(void)readLE32(); // Read & ignore file size
|
||||
(void)readLE32(); // Read & ignore creator bytes
|
||||
(void)readLE32(); // Read & ignore position of image data
|
||||
(void)readLE32(); // Read & ignore header size
|
||||
if(width) *width = readLE32();
|
||||
if(height) {
|
||||
if (width)
|
||||
*width = readLE32();
|
||||
if (height) {
|
||||
int32_t h = readLE32(); // Don't abs() this, may be a macro
|
||||
if(h < 0) h = -h; // Do manually instead
|
||||
if (h < 0)
|
||||
h = -h; // Do manually instead
|
||||
*height = h;
|
||||
}
|
||||
status = IMAGE_SUCCESS; // YAY.
|
||||
|
|
@ -627,7 +643,8 @@ ImageReturnCode Adafruit_ImageReader::bmpDimensions(
|
|||
@return Unsigned 16-bit value, native endianism.
|
||||
*/
|
||||
uint16_t Adafruit_ImageReader::readLE16(void) {
|
||||
#if !defined(ESP32) && !defined(ESP8266) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#if !defined(ESP32) && !defined(ESP8266) && \
|
||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
// Read directly into result -- BMP data and variable both little-endian.
|
||||
uint16_t result;
|
||||
file.read(&result, sizeof result);
|
||||
|
|
@ -645,17 +662,16 @@ uint16_t Adafruit_ImageReader::readLE16(void) {
|
|||
@return Unsigned 32-bit value, native endianism.
|
||||
*/
|
||||
uint32_t Adafruit_ImageReader::readLE32(void) {
|
||||
#if !defined(ESP32) && !defined(ESP8266) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#if !defined(ESP32) && !defined(ESP8266) && \
|
||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
// Read directly into result -- BMP data and variable both little-endian.
|
||||
uint32_t result;
|
||||
file.read(&result, sizeof result);
|
||||
return result;
|
||||
#else
|
||||
// Big-endian or unknown. Byte-by-byte read will perform reversal if needed.
|
||||
return file.read() |
|
||||
((uint32_t)file.read() << 8) |
|
||||
((uint32_t)file.read() << 16) |
|
||||
((uint32_t)file.read() << 24);
|
||||
return file.read() | ((uint32_t)file.read() << 8) |
|
||||
((uint32_t)file.read() << 16) | ((uint32_t)file.read() << 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -669,12 +685,12 @@ uint32_t Adafruit_ImageReader::readLE32(void) {
|
|||
@return None (void).
|
||||
*/
|
||||
void Adafruit_ImageReader::printStatus(ImageReturnCode stat, Stream &stream) {
|
||||
if(stat == IMAGE_SUCCESS)
|
||||
if (stat == IMAGE_SUCCESS)
|
||||
stream.println(F("Success!"));
|
||||
else if(stat == IMAGE_ERR_FILE_NOT_FOUND)
|
||||
else if (stat == IMAGE_ERR_FILE_NOT_FOUND)
|
||||
stream.println(F("File not found."));
|
||||
else if(stat == IMAGE_ERR_FORMAT)
|
||||
else if (stat == IMAGE_ERR_FORMAT)
|
||||
stream.println(F("Not a supported BMP variant."));
|
||||
else if(stat == IMAGE_ERR_MALLOC)
|
||||
else if (stat == IMAGE_ERR_MALLOC)
|
||||
stream.println(F("Malloc failed (insufficient RAM)."));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
#ifndef __ADAFRUIT_IMAGE_READER_H__
|
||||
#define __ADAFRUIT_IMAGE_READER_H__
|
||||
|
||||
#include "Adafruit_SPITFT.h"
|
||||
#include "Adafruit_SPIFlash.h"
|
||||
#include "Adafruit_SPITFT.h"
|
||||
|
||||
/** Status codes returned by drawBMP() and loadBMP() */
|
||||
enum ImageReturnCode {
|
||||
|
|
@ -39,7 +39,7 @@ enum ImageFormat {
|
|||
ImageReader.loadBMP() and Image.draw(), not ImageReader.drawBMP().
|
||||
*/
|
||||
class Adafruit_Image {
|
||||
public:
|
||||
public:
|
||||
Adafruit_Image(void);
|
||||
~Adafruit_Image(void);
|
||||
int16_t width(void) const; // Return image width in pixels
|
||||
|
|
@ -65,7 +65,8 @@ class Adafruit_Image {
|
|||
NULL otherwise.
|
||||
*/
|
||||
GFXcanvas1 *getMask(void) const { return mask; };
|
||||
protected:
|
||||
|
||||
protected:
|
||||
// MOST OF THESE ARE NOT SUPPORTED YET -- WIP
|
||||
union { // Single pointer, only one variant is used:
|
||||
GFXcanvas1 *canvas1; ///< Canvas object if 1bpp format
|
||||
|
|
@ -92,19 +93,20 @@ class Adafruit_Image {
|
|||
for use.
|
||||
*/
|
||||
class Adafruit_ImageReader {
|
||||
public:
|
||||
public:
|
||||
Adafruit_ImageReader(FatFileSystem &fs);
|
||||
~Adafruit_ImageReader(void);
|
||||
ImageReturnCode drawBMP(char *filename, Adafruit_SPITFT &tft,
|
||||
int16_t x, int16_t y, boolean transact = true);
|
||||
ImageReturnCode drawBMP(char *filename, Adafruit_SPITFT &tft, int16_t x,
|
||||
int16_t y, boolean transact = true);
|
||||
ImageReturnCode loadBMP(char *filename, Adafruit_Image &img);
|
||||
ImageReturnCode bmpDimensions(char *filename, int32_t *w, int32_t *h);
|
||||
void printStatus(ImageReturnCode stat, Stream &stream=Serial);
|
||||
private:
|
||||
void printStatus(ImageReturnCode stat, Stream &stream = Serial);
|
||||
|
||||
private:
|
||||
FatFileSystem *filesys;
|
||||
File file;
|
||||
ImageReturnCode coreBMP(char *filename, Adafruit_SPITFT *tft,
|
||||
uint16_t *dest, int16_t x, int16_t y, Adafruit_Image *img,
|
||||
ImageReturnCode coreBMP(char *filename, Adafruit_SPITFT *tft, uint16_t *dest,
|
||||
int16_t x, int16_t y, Adafruit_Image *img,
|
||||
boolean transact);
|
||||
uint16_t readLE16(void);
|
||||
uint32_t readLE32(void);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@
|
|||
*/
|
||||
void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
|
||||
int16_t col = x, row = y;
|
||||
if(format == IMAGE_1 ) {
|
||||
if (format == IMAGE_1) {
|
||||
uint8_t *buffer = canvas.canvas1->getBuffer();
|
||||
uint8_t i, c;
|
||||
while(row < y + canvas.canvas1->height()) {
|
||||
while (row < y + canvas.canvas1->height()) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((*buffer & (0x80 >> i)) > 0) {
|
||||
c = EPD_BLACK; // try to infer black
|
||||
|
|
@ -34,10 +34,10 @@ void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
|
|||
}
|
||||
buffer++;
|
||||
};
|
||||
} else if(format == IMAGE_8 ) {
|
||||
} else if(format == IMAGE_16) {
|
||||
} else if (format == IMAGE_8) {
|
||||
} else if (format == IMAGE_16) {
|
||||
uint16_t *buffer = canvas.canvas16->getBuffer();
|
||||
while(row < y + canvas.canvas16->height()) {
|
||||
while (row < y + canvas.canvas16->height()) {
|
||||
// RGB in 565 format
|
||||
uint8_t r = (*buffer & 0xf800) >> 8;
|
||||
uint8_t g = (*buffer & 0x07e0) >> 3;
|
||||
|
|
@ -49,7 +49,7 @@ void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
|
|||
} else if ((r >= 0x80) && (g >= 0x80) && (b >= 0x80)) {
|
||||
c = EPD_WHITE;
|
||||
} else if (r >= 0x80) {
|
||||
c = EPD_RED; //try to infer red color
|
||||
c = EPD_RED; // try to infer red color
|
||||
}
|
||||
|
||||
epd.writePixel(col, row, c);
|
||||
|
|
|
|||
|
|
@ -15,17 +15,18 @@
|
|||
#ifndef __ADAFRUIT_IMAGE_READER_EPD_H__
|
||||
#define __ADAFRUIT_IMAGE_READER_EPD_H__
|
||||
|
||||
#include "Adafruit_ImageReader.h"
|
||||
#include "Adafruit_EPD.h"
|
||||
#include "Adafruit_ImageReader.h"
|
||||
|
||||
/*!
|
||||
@brief Data bundle returned with an image loaded to RAM. Used by
|
||||
ImageReader.loadBMP() and Image.draw(), not ImageReader.drawBMP().
|
||||
*/
|
||||
class Adafruit_Image_EPD : public Adafruit_Image {
|
||||
public:
|
||||
public:
|
||||
void draw(Adafruit_EPD &epd, int16_t x, int16_t y);
|
||||
protected:
|
||||
|
||||
protected:
|
||||
friend class Adafruit_ImageReader; ///< Loading occurs here
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Adafruit_ImageReader [](https://travis-ci.com/adafruit/Adafruit_ImageReader)
|
||||
# Adafruit_ImageReader 
|
||||
|
||||
Companion library for Adafruit_GFX to load images from SD card.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name=Adafruit ImageReader Library
|
||||
version=2.3.3
|
||||
version=2.3.4
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Companion library for Adafruit_GFX and Adafruit_EPD to load images from SD card.
|
||||
|
|
@ -7,4 +7,4 @@ paragraph=Install this library in addition to Adafruit_GFX and the display libra
|
|||
category=Display
|
||||
url=https://github.com/adafruit/Adafruit_ImageReader
|
||||
architectures=*
|
||||
depends=Adafruit GFX Library, Adafruit ST7735 and ST7789 Library, Adafruit HX8357 Library, Adafruit ILI9341, Adafruit SSD1351 library, Adafruit SSD1331 OLED Driver Library for Arduino, Adafruit SPIFlash, SdFat - Adafruit Fork, Adafruit EPD, Adafruit seesaw Library
|
||||
depends=Adafruit GFX Library, Adafruit ST7735 and ST7789 Library, Adafruit HX8357 Library, Adafruit ILI9341, Adafruit SSD1351 library, Adafruit SSD1331 OLED Driver Library for Arduino, Adafruit SPIFlash, SdFat - Adafruit Fork, Adafruit EPD
|
||||
Loading…
Reference in a new issue