added code for mp3 and jpeg parsing
added interface for data sources
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
*.pdf
|
||||||
|
*.PDF
|
||||||
|
*.tar.gz
|
||||||
|
|
||||||
|
build-*
|
||||||
|
a.out
|
||||||
|
CMakeLists.txt.*
|
||||||
42
data/formats/DataSourceFile.h
Normal file
42
data/formats/DataSourceFile.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../ext/sd/File.h"
|
||||||
|
|
||||||
|
/** data source using our filesystem */
|
||||||
|
class DataSourceFile {
|
||||||
|
|
||||||
|
File* f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** empty ctor */
|
||||||
|
DataSourceFile() : f(nullptr) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ctor with the filesystem file to wrap */
|
||||||
|
DataSourceFile(File& f) : f(&f) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get the current position */
|
||||||
|
uint32_t curPos() const {
|
||||||
|
return f->curPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** seek to the given position */
|
||||||
|
void seekTo(uint32_t newPos) {
|
||||||
|
f->seekTo(newPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read x bytes from the input into dst */
|
||||||
|
uint32_t read(uint32_t size, uint8_t* dst) {
|
||||||
|
return f->read(size, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read an entity */
|
||||||
|
template <typename T> void readType(T& dst) {
|
||||||
|
read(sizeof(T), (uint8_t*)&dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
38
data/formats/DataSourceMemory.h
Normal file
38
data/formats/DataSourceMemory.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/** data source wrapping the memory */
|
||||||
|
template <typename File> class DataSourceMemory {
|
||||||
|
|
||||||
|
const uint8_t* src;
|
||||||
|
const uint32_t len;
|
||||||
|
uint32_t pos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** ctor with the memory region */
|
||||||
|
DataSourceMemory(const uint8_t* src, const uint32_t len) : src(src), len(len) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get the current position */
|
||||||
|
uint32_t curPos() const {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** seek to the given position */
|
||||||
|
void seekTo(uint32_t newPos) {
|
||||||
|
pos = newPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read an entity */
|
||||||
|
template <typename T> void readType(T& dst) {
|
||||||
|
read(sizeof(T), &dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read x bytes from the input into dst */
|
||||||
|
template <typename T> void read(uint32_t size, T* dst) {
|
||||||
|
memcpy(dst, &src[pos], size);
|
||||||
|
pos += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
50
data/formats/DataSourcePosixFile.h
Normal file
50
data/formats/DataSourcePosixFile.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
/** file on the desktop (posix) filesystem */
|
||||||
|
class DataSourcePosixFile {
|
||||||
|
|
||||||
|
FILE* f = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DataSourcePosixFile() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSourcePosixFile(const char* file) {
|
||||||
|
f = fopen(file, "rw");
|
||||||
|
if (!f) {
|
||||||
|
throw std::runtime_error(std::string("failed to open file: ") + file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~DataSourcePosixFile() {
|
||||||
|
if (f) {fclose(f);}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t curPos() const {
|
||||||
|
return ftell(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void seekTo(uint32_t pos) {
|
||||||
|
fseek(f, pos, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t read(uint32_t bytes, uint8_t* dst) {
|
||||||
|
return fread(dst, bytes, 1, f) * bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t write(uint32_t bytes, const uint8_t* src) {
|
||||||
|
return fwrite(src, bytes, 1, f) * bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read an entity */
|
||||||
|
template <typename T> void readType(T& dst) {
|
||||||
|
read(sizeof(T), (uint8_t*) &dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
199
data/formats/jpeg/JPEGDEC.cpp
Normal file
199
data/formats/jpeg/JPEGDEC.cpp
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
//
|
||||||
|
// JPEG Decoder
|
||||||
|
//
|
||||||
|
// written by Larry Bank
|
||||||
|
// bitbank@pobox.com
|
||||||
|
// 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.c"
|
||||||
|
|
||||||
|
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() */
|
||||||
|
|
||||||
|
#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() */
|
||||||
|
|
||||||
|
int JPEGDEC::decodeDither(uint8_t *pDither, int iOptions)
|
||||||
|
{
|
||||||
|
_jpeg.iOptions = iOptions;
|
||||||
|
_jpeg.pDitherBuffer = pDither;
|
||||||
|
return DecodeJPEG(&_jpeg);
|
||||||
|
}
|
||||||
259
data/formats/jpeg/JPEGDEC.h
Normal file
259
data/formats/jpeg/JPEGDEC.h
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
#ifndef __JPEGDEC__
|
||||||
|
#define __JPEGDEC__
|
||||||
|
#if defined( __MACH__ ) || defined( __LINUX__ ) || defined( __MCUXPRESSO )
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#else
|
||||||
|
#include <Arduino.h>
|
||||||
|
#endif
|
||||||
|
#ifndef PROGMEM
|
||||||
|
#define memcpy_P memcpy
|
||||||
|
#define PROGMEM
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// JPEG Decoder
|
||||||
|
// Written by Larry Bank
|
||||||
|
// Copyright (c) 2020 BitBank Software, Inc.
|
||||||
|
//
|
||||||
|
// Designed to decode baseline JPEG images (8 or 24-bpp)
|
||||||
|
// using less than 22K of RAM
|
||||||
|
//
|
||||||
|
|
||||||
|
/* Defines and variables */
|
||||||
|
#define FILE_HIGHWATER 1536
|
||||||
|
#define JPEG_FILE_BUF_SIZE 2048
|
||||||
|
#define HUFF_TABLEN 273
|
||||||
|
#define HUFF11SIZE (1<<11)
|
||||||
|
#define DC_TABLE_SIZE 1024
|
||||||
|
#define DCTSIZE 64
|
||||||
|
#define MAX_MCU_COUNT 6
|
||||||
|
#define MAX_COMPS_IN_SCAN 4
|
||||||
|
#define MAX_BUFFERED_PIXELS 2048
|
||||||
|
|
||||||
|
// Decoder options
|
||||||
|
#define JPEG_AUTO_ROTATE 1
|
||||||
|
#define JPEG_SCALE_HALF 2
|
||||||
|
#define JPEG_SCALE_QUARTER 4
|
||||||
|
#define JPEG_SCALE_EIGHTH 8
|
||||||
|
#define JPEG_LE_PIXELS 16
|
||||||
|
#define JPEG_EXIF_THUMBNAIL 32
|
||||||
|
#define JPEG_LUMA_ONLY 64
|
||||||
|
|
||||||
|
#define MCU0 (DCTSIZE * 0)
|
||||||
|
#define MCU1 (DCTSIZE * 1)
|
||||||
|
#define MCU2 (DCTSIZE * 2)
|
||||||
|
#define MCU3 (DCTSIZE * 3)
|
||||||
|
#define MCU4 (DCTSIZE * 4)
|
||||||
|
#define MCU5 (DCTSIZE * 5)
|
||||||
|
|
||||||
|
// Pixel types (defaults to little endian RGB565)
|
||||||
|
enum {
|
||||||
|
RGB565_LITTLE_ENDIAN = 0,
|
||||||
|
RGB565_BIG_ENDIAN,
|
||||||
|
EIGHT_BIT_GRAYSCALE,
|
||||||
|
FOUR_BIT_DITHERED,
|
||||||
|
TWO_BIT_DITHERED,
|
||||||
|
ONE_BIT_DITHERED,
|
||||||
|
INVALID_PIXEL_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JPEG_MEM_RAM=0,
|
||||||
|
JPEG_MEM_FLASH
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error codes returned by getLastError()
|
||||||
|
enum {
|
||||||
|
JPEG_SUCCESS = 0,
|
||||||
|
JPEG_INVALID_PARAMETER,
|
||||||
|
JPEG_DECODE_ERROR,
|
||||||
|
JPEG_UNSUPPORTED_FEATURE,
|
||||||
|
JPEG_INVALID_FILE
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct buffered_bits
|
||||||
|
{
|
||||||
|
unsigned char *pBuf; // buffer pointer
|
||||||
|
uint32_t ulBits; // buffered bits
|
||||||
|
uint32_t ulBitOff; // current bit offset
|
||||||
|
} BUFFERED_BITS;
|
||||||
|
|
||||||
|
typedef struct jpeg_file_tag
|
||||||
|
{
|
||||||
|
int32_t iPos; // current file position
|
||||||
|
int32_t iSize; // file size
|
||||||
|
uint8_t *pData; // memory file pointer
|
||||||
|
void * fHandle; // class pointer to File/SdFat or whatever you want
|
||||||
|
} JPEGFILE;
|
||||||
|
|
||||||
|
typedef struct jpeg_draw_tag
|
||||||
|
{
|
||||||
|
int x, y; // upper left corner of current MCU
|
||||||
|
int iWidth, iHeight; // size of this MCU
|
||||||
|
int iBpp; // bit depth of the pixels (8 or 16)
|
||||||
|
uint16_t *pPixels; // 16-bit pixels
|
||||||
|
} JPEGDRAW;
|
||||||
|
|
||||||
|
// Callback function prototypes
|
||||||
|
typedef int32_t (JPEG_READ_CALLBACK)(JPEGFILE *pFile, uint8_t *pBuf, int32_t iLen);
|
||||||
|
typedef int32_t (JPEG_SEEK_CALLBACK)(JPEGFILE *pFile, int32_t iPosition);
|
||||||
|
typedef int (JPEG_DRAW_CALLBACK)(JPEGDRAW *pDraw);
|
||||||
|
typedef void * (JPEG_OPEN_CALLBACK)(const char *szFilename, int32_t *pFileSize);
|
||||||
|
typedef void (JPEG_CLOSE_CALLBACK)(void *pHandle);
|
||||||
|
|
||||||
|
/* JPEG color component info */
|
||||||
|
typedef struct _jpegcompinfo
|
||||||
|
{
|
||||||
|
// These values are fixed over the whole image
|
||||||
|
// For compression, they must be supplied by the user interface
|
||||||
|
// for decompression, they are read from the SOF marker.
|
||||||
|
unsigned char component_needed; /* do we need the value of this component? */
|
||||||
|
unsigned char component_id; /* identifier for this component (0..255) */
|
||||||
|
unsigned char component_index; /* its index in SOF or cinfo->comp_info[] */
|
||||||
|
//unsigned char h_samp_factor; /* horizontal sampling factor (1..4) */
|
||||||
|
//unsigned char v_samp_factor; /* vertical sampling factor (1..4) */
|
||||||
|
unsigned char quant_tbl_no; /* quantization table selector (0..3) */
|
||||||
|
// These values may vary between scans
|
||||||
|
// For compression, they must be supplied by the user interface
|
||||||
|
// for decompression, they are read from the SOS marker.
|
||||||
|
unsigned char dc_tbl_no; /* DC entropy table selector (0..3) */
|
||||||
|
unsigned char ac_tbl_no; /* AC entropy table selector (0..3) */
|
||||||
|
// These values are computed during compression or decompression startup
|
||||||
|
//int true_comp_width; /* component's image width in samples */
|
||||||
|
//int true_comp_height; /* component's image height in samples */
|
||||||
|
// the above are the logical dimensions of the downsampled image
|
||||||
|
// These values are computed before starting a scan of the component
|
||||||
|
//int MCU_width; /* number of blocks per MCU, horizontally */
|
||||||
|
//int MCU_height; /* number of blocks per MCU, vertically */
|
||||||
|
//int MCU_blocks; /* MCU_width * MCU_height */
|
||||||
|
//int downsampled_width; /* image width in samples, after expansion */
|
||||||
|
//int downsampled_height; /* image height in samples, after expansion */
|
||||||
|
// the above are the true_comp_xxx values rounded up to multiples of
|
||||||
|
// the MCU dimensions; these are the working dimensions of the array
|
||||||
|
// as it is passed through the DCT or IDCT step. NOTE: these values
|
||||||
|
// differ depending on whether the component is interleaved or not!!
|
||||||
|
// This flag is used only for decompression. In cases where some of the
|
||||||
|
// components will be ignored (eg grayscale output from YCbCr image),
|
||||||
|
// we can skip IDCT etc. computations for the unused components.
|
||||||
|
} JPEGCOMPINFO;
|
||||||
|
|
||||||
|
//
|
||||||
|
// our private structure to hold a JPEG image decode state
|
||||||
|
//
|
||||||
|
typedef struct jpeg_image_tag
|
||||||
|
{
|
||||||
|
int iWidth, iHeight; // image size
|
||||||
|
int iThumbWidth, iThumbHeight; // thumbnail size (if present)
|
||||||
|
int iThumbData; // offset to image data
|
||||||
|
int iXOffset, iYOffset; // placement on the display
|
||||||
|
uint8_t ucBpp, ucSubSample, ucHuffTableUsed;
|
||||||
|
uint8_t ucMode, ucOrientation, ucHasThumb, b11Bit;
|
||||||
|
uint8_t ucComponentsInScan, cApproxBitsLow, cApproxBitsHigh;
|
||||||
|
uint8_t iScanStart, iScanEnd, ucFF, ucNumComponents;
|
||||||
|
uint8_t ucACTable, ucDCTable, ucMaxACCol, ucMaxACRow;
|
||||||
|
uint8_t ucMemType, ucPixelType;
|
||||||
|
int iEXIF; // Offset to EXIF 'TIFF' file
|
||||||
|
int iError;
|
||||||
|
int iOptions;
|
||||||
|
int iVLCOff; // current VLC data offset
|
||||||
|
int iVLCSize; // current quantity of data in the VLC buffer
|
||||||
|
int iResInterval, iResCount; // restart interval
|
||||||
|
int iMaxMCUs; // max MCUs of pixels per JPEGDraw call
|
||||||
|
JPEG_READ_CALLBACK *pfnRead;
|
||||||
|
JPEG_SEEK_CALLBACK *pfnSeek;
|
||||||
|
JPEG_DRAW_CALLBACK *pfnDraw;
|
||||||
|
JPEG_OPEN_CALLBACK *pfnOpen;
|
||||||
|
JPEG_CLOSE_CALLBACK *pfnClose;
|
||||||
|
JPEGCOMPINFO JPCI[MAX_COMPS_IN_SCAN]; /* Max color components */
|
||||||
|
JPEGFILE JPEGFile;
|
||||||
|
BUFFERED_BITS bb;
|
||||||
|
uint8_t *pDitherBuffer; // provided externally to do Floyd-Steinberg dithering
|
||||||
|
uint16_t usPixels[MAX_BUFFERED_PIXELS];
|
||||||
|
int16_t sMCUs[DCTSIZE * MAX_MCU_COUNT]; // 4:2:0 needs 6 DCT blocks per MCU
|
||||||
|
int16_t sQuantTable[DCTSIZE*4]; // quantization tables
|
||||||
|
uint8_t ucFileBuf[JPEG_FILE_BUF_SIZE]; // holds temp data and pixel stack
|
||||||
|
uint8_t ucHuffDC[DC_TABLE_SIZE * 2]; // up to 2 'short' tables
|
||||||
|
uint16_t usHuffAC[HUFF11SIZE * 2];
|
||||||
|
} JPEGIMAGE;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#if defined(__has_include) && __has_include(<FS.h>)
|
||||||
|
#include "FS.h"
|
||||||
|
#endif
|
||||||
|
#define JPEG_STATIC static
|
||||||
|
//
|
||||||
|
// The JPEGDEC class wraps portable C code which does the actual work
|
||||||
|
//
|
||||||
|
class JPEGDEC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int openRAM(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw);
|
||||||
|
int openFLASH(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw);
|
||||||
|
int open(const char *szFilename, JPEG_OPEN_CALLBACK *pfnOpen, JPEG_CLOSE_CALLBACK *pfnClose, JPEG_READ_CALLBACK *pfnRead, JPEG_SEEK_CALLBACK *pfnSeek, JPEG_DRAW_CALLBACK *pfnDraw);
|
||||||
|
#ifdef FS_H
|
||||||
|
int open(File &file, JPEG_DRAW_CALLBACK *pfnDraw);
|
||||||
|
#endif
|
||||||
|
void close();
|
||||||
|
int decode(int x, int y, int iOptions);
|
||||||
|
int decodeDither(uint8_t *pDither, int iOptions);
|
||||||
|
int getOrientation();
|
||||||
|
int getWidth();
|
||||||
|
int getHeight();
|
||||||
|
int getBpp();
|
||||||
|
int getSubSample();
|
||||||
|
int hasThumb();
|
||||||
|
int getThumbWidth();
|
||||||
|
int getThumbHeight();
|
||||||
|
int getLastError();
|
||||||
|
void setPixelType(int iType); // defaults to little endian
|
||||||
|
void setMaxOutputSize(int iMaxMCUs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
JPEGIMAGE _jpeg;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#define JPEG_STATIC
|
||||||
|
int JPEG_openRAM(JPEGIMAGE *pJPEG, uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw);
|
||||||
|
int JPEG_openFile(JPEGIMAGE *pJPEG, const char *szFilename, JPEG_DRAW_CALLBACK *pfnDraw);
|
||||||
|
int JPEG_getWidth(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getHeight(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_decode(JPEGIMAGE *pJPEG, int x, int y, int iOptions);
|
||||||
|
int JPEG_decodeDither(JPEGIMAGE *pJPEG, uint8_t *pDither, int iOptions);
|
||||||
|
void JPEG_close(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getLastError(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getOrientation(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getBpp(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getSubSample(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_hasThumb(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getThumbWidth(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getThumbHeight(JPEGIMAGE *pJPEG);
|
||||||
|
int JPEG_getLastError(JPEGIMAGE *pJPEG);
|
||||||
|
void JPEG_setPixelType(JPEGIMAGE *pJPEG, int iType); // defaults to little endian
|
||||||
|
void JPEG_setMaxOutputSize(JPEGIMAGE *pJPEG, int iMaxMCUs);
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// Due to unaligned memory causing an exception, we have to do these macros the slow way
|
||||||
|
#define INTELSHORT(p) ((*p) + (*(p+1)<<8))
|
||||||
|
#define INTELLONG(p) ((*p) + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24))
|
||||||
|
#define MOTOSHORT(p) (((*(p))<<8) + (*(p+1)))
|
||||||
|
#define MOTOLONG(p) (((*p)<<24) + ((*(p+1))<<16) + ((*(p+2))<<8) + (*(p+3)))
|
||||||
|
|
||||||
|
// Must be a 32-bit target processor
|
||||||
|
#define REGISTER_WIDTH 32
|
||||||
|
|
||||||
|
#endif // __JPEGDEC__
|
||||||
3436
data/formats/jpeg/jpeg.c
Normal file
3436
data/formats/jpeg/jpeg.c
Normal file
File diff suppressed because it is too large
Load Diff
1
data/formats/jpeg/readme.md
Normal file
1
data/formats/jpeg/readme.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://github.com/bitbank2/JPEGDEC/tree/master/src
|
||||||
24
data/formats/jpeg/test.cpp
Normal file
24
data/formats/jpeg/test.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "JPEGDEC.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "testimage.h"
|
||||||
|
|
||||||
|
// gcc -D__LINUX__ jpeg.c JPEGDEC.cpp test.cpp
|
||||||
|
|
||||||
|
int drawJPEG(JPEGDRAW* pDraw) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
JPEGDEC jpeg;
|
||||||
|
int res = jpeg.openRAM(aaa_jpg, aaa_jpg_len, drawJPEG);
|
||||||
|
|
||||||
|
std::cout << res << std::endl;
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
jpeg.setPixelType(RGB565_BIG_ENDIAN);
|
||||||
|
jpeg.decode(0, 0, 0);//40, 100, JPEG_SCALE_QUARTER | JPEG_EXIF_THUMBNAIL);
|
||||||
|
jpeg.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1855
data/formats/mp3/minimp3.h
Normal file
1855
data/formats/mp3/minimp3.h
Normal file
File diff suppressed because it is too large
Load Diff
1
data/formats/mp3/readme.md
Normal file
1
data/formats/mp3/readme.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://github.com/lieff/minimp3
|
||||||
Reference in New Issue
Block a user