Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions 3rd-party/JPEGDEC/JPEGDEC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
add_library(JPEGDEC INTERFACE)

target_sources(cover_art INTERFACE
${CMAKE_CURRENT_LIST_DIR}/JPEGDEC.cpp
)

target_include_directories(cover_art INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
222 changes: 222 additions & 0 deletions 3rd-party/JPEGDEC/JPEGDEC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
//
// JPEG Decoder
//
// written by Larry Bank
// [email protected]
// Arduino port started 8/2/2020
// Original JPEG code written 26+ years ago :)
// The goal of this code is to decode baseline JPEG images
// using no more than 18K of RAM (if sent directly to an LCD display)
//
// Copyright 2020 BitBank Software, Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===========================================================================
//
#include "JPEGDEC.h"

// forward references
JPEG_STATIC int JPEGInit(JPEGIMAGE *pJPEG);
JPEG_STATIC int JPEGParseInfo(JPEGIMAGE *pPage, int bExtractThumb);
JPEG_STATIC void JPEGGetMoreData(JPEGIMAGE *pPage);
JPEG_STATIC int DecodeJPEG(JPEGIMAGE *pImage);

// Include the C code which does the actual work
#include "jpeg.inl"

void JPEGDEC::setPixelType(int iType)
{
if (iType >= 0 && iType < INVALID_PIXEL_TYPE)
_jpeg.ucPixelType = (uint8_t)iType;
else
_jpeg.iError = JPEG_INVALID_PARAMETER;
} /* setPixelType() */

void JPEGDEC::setMaxOutputSize(int iMaxMCUs)
{
if (iMaxMCUs < 1)
iMaxMCUs = 1; // don't allow invalid value
_jpeg.iMaxMCUs = iMaxMCUs;
} /* setMaxOutputSize() */
//
// Memory initialization
//
int JPEGDEC::openRAM(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw)
{
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
_jpeg.ucMemType = JPEG_MEM_RAM;
_jpeg.pfnRead = readRAM;
_jpeg.pfnSeek = seekMem;
_jpeg.pfnDraw = pfnDraw;
_jpeg.pfnOpen = NULL;
_jpeg.pfnClose = NULL;
_jpeg.JPEGFile.iSize = iDataSize;
_jpeg.JPEGFile.pData = pData;
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
return JPEGInit(&_jpeg);
} /* openRAM() */

int JPEGDEC::openFLASH(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw)
{
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
_jpeg.ucMemType = JPEG_MEM_FLASH;
_jpeg.pfnRead = readFLASH;
_jpeg.pfnSeek = seekMem;
_jpeg.pfnDraw = pfnDraw;
_jpeg.pfnOpen = NULL;
_jpeg.pfnClose = NULL;
_jpeg.JPEGFile.iSize = iDataSize;
_jpeg.JPEGFile.pData = pData;
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
return JPEGInit(&_jpeg);
} /* openRAM() */

int JPEGDEC::getOrientation()
{
return (int)_jpeg.ucOrientation;
} /* getOrientation() */

int JPEGDEC::getLastError()
{
return _jpeg.iError;
} /* getLastError() */

int JPEGDEC::getWidth()
{
return _jpeg.iWidth;
} /* getWidth() */

int JPEGDEC::getHeight()
{
return _jpeg.iHeight;
} /* getHeight() */

int JPEGDEC::hasThumb()
{
return (int)_jpeg.ucHasThumb;
} /* hasThumb() */

int JPEGDEC::getThumbWidth()
{
return _jpeg.iThumbWidth;
} /* getThumbWidth() */

int JPEGDEC::getThumbHeight()
{
return _jpeg.iThumbHeight;
} /* getThumbHeight() */

int JPEGDEC::getBpp()
{
return (int)_jpeg.ucBpp;
} /* getBpp() */

int JPEGDEC::getSubSample()
{
return (int)_jpeg.ucSubSample;
} /* getSubSample() */

//
// File (SD/MMC) based initialization
//
int JPEGDEC::open(const char *szFilename, JPEG_OPEN_CALLBACK *pfnOpen, JPEG_CLOSE_CALLBACK *pfnClose, JPEG_READ_CALLBACK *pfnRead, JPEG_SEEK_CALLBACK *pfnSeek, JPEG_DRAW_CALLBACK *pfnDraw)
{
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
_jpeg.pfnRead = pfnRead;
_jpeg.pfnSeek = pfnSeek;
_jpeg.pfnDraw = pfnDraw;
_jpeg.pfnOpen = pfnOpen;
_jpeg.pfnClose = pfnClose;
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
_jpeg.JPEGFile.fHandle = (*pfnOpen)(szFilename, &_jpeg.JPEGFile.iSize);
if (_jpeg.JPEGFile.fHandle == NULL)
return 0;
return JPEGInit(&_jpeg);

} /* open() */

//
// data stream initialization
//
int JPEGDEC::open(void *fHandle, int iDataSize, JPEG_CLOSE_CALLBACK *pfnClose, JPEG_READ_CALLBACK *pfnRead, JPEG_SEEK_CALLBACK *pfnSeek, JPEG_DRAW_CALLBACK *pfnDraw)
{
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
_jpeg.pfnRead = pfnRead;
_jpeg.pfnSeek = pfnSeek;
_jpeg.pfnDraw = pfnDraw;
_jpeg.pfnClose = pfnClose;
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
_jpeg.JPEGFile.iSize = iDataSize;
_jpeg.JPEGFile.fHandle = fHandle;
return JPEGInit(&_jpeg);
} /* open() */

#ifdef FS_H
static int32_t FileRead(JPEGFILE *handle, uint8_t *buffer, int32_t length)
{
return ((File *)(handle->fHandle))->read(buffer, length);
}
static int32_t FileSeek(JPEGFILE *handle, int32_t position)
{
return ((File *)(handle->fHandle))->seek(position);
}
static void FileClose(void *handle)
{
((File *)handle)->close();
}

int JPEGDEC::open(File &file, JPEG_DRAW_CALLBACK *pfnDraw)
{
if (!file) return 0;
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
_jpeg.pfnRead = FileRead;
_jpeg.pfnSeek = FileSeek;
_jpeg.pfnClose = FileClose;
_jpeg.pfnDraw = pfnDraw;
_jpeg.iMaxMCUs = 1000;
_jpeg.JPEGFile.fHandle = &file;
_jpeg.JPEGFile.iSize = file.size();
return JPEGInit(&_jpeg);
}
#endif // FS_H

void JPEGDEC::close()
{
if (_jpeg.pfnClose)
(*_jpeg.pfnClose)(_jpeg.JPEGFile.fHandle);
} /* close() */

//
// Decode the image
// returns:
// 1 = good result
// 0 = error
//
int JPEGDEC::decode(int x, int y, int iOptions)
{
_jpeg.iXOffset = x;
_jpeg.iYOffset = y;
_jpeg.iOptions = iOptions;
return DecodeJPEG(&_jpeg);
} /* decode() */
//
// set draw callback user pointer variable
//
void JPEGDEC::setUserPointer(void *p)
{
_jpeg.pUser = p;
}

int JPEGDEC::decodeDither(uint8_t *pDither, int iOptions)
{
_jpeg.iOptions = iOptions;
_jpeg.pDitherBuffer = pDither;
return DecodeJPEG(&_jpeg);
}
Loading