⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpeg.h

📁 一个机器人开发的相关嵌入式开发源码
💻 H
字号:
/** 
 *  A JPEG decompressor, targeted for the GameBoy Advance (although there
 * should be no machine-specific aspects if you disable JPEG_USE_IWRAM
 * and JPEG_MARK_TIME).  On the GBA it consumes, all with slight potential
 * variance:
 *
 * 3348 bytes of IWRAM, temporary
 * 7756 bytes of ROM
 * 4720 bytes of stack space, usually in IWRAM
 * 350 milliseconds for decompressing a representative image
 * 
 * It has a low capacitance for unusual JPEGs.  They cannot be progressive,
 * use arithmetic coding, have more than 4 components in a scan, and must be
 * 8-bit.  They can be colour or grayscale, and any component scaling factors
 * are valid (unless if JPEG_HANDLE_ANY_FACTORS is reset, in which case only
 * 2:1:1 is allowed).  The maximum component scale factors cannot be three.  In
 * general, you'll be all right, but if it doesn't like your input it will not
 * react sensibly in embedded.
 * 
  * - Burton Radons (loth@users.sourceforge.net)
 */

#ifndef JPEG_HANDLE_ANY_FACTORS
#define JPEG_HANDLE_ANY_FACTORS 1
  /**< If this is set, any component factors are valid.  Otherwise
   * it will only handle 2:1:1 (the typical form that sacrifices colour
   * resolution).  Note that Photoshop will only generate such files if you
   * use Save for Web.  Resetting this saves 508 bytes of IWRAM.
   */
#endif /* JPEG_HANDLE_ANY_FACTORS */
   
#ifndef JPEG_FASTER_M211
#define JPEG_FASTER_M211 1
  /**< If this is set, then the most common JPEG format is not given
   * special, faster treatment.  You must set JPEG_HANDLE_ANY_FACTORS
   * in this case, or you will not see anything.  Resetting this saves
   * 532 bytes of IWRAM, at the cost of speed.
   */
#endif /* JPEG_FASTER_M211 */
   
#define JPEG_DCTSIZE 8
  /**< The number of samples across and down a JPEG DCT.  This cannot be
   * configured, as the inverse DCT only handles 8x8.
   */

#define JPEG_DCTSIZE2 (JPEG_DCTSIZE * JPEG_DCTSIZE)
  /**< The number of samples in a full 2-D DCT. */
  
#ifndef JPEG_MAXIMUM_COMPONENTS
#define JPEG_MAXIMUM_COMPONENTS 4
  /**< The maximum number of components that can be involved in an image.
    * Each value costs 8 bytes of stack space and 8 bytes of allocations.
    */
#endif /* JPEG_MAXIMUM_SCAN_COMPONENTS */

#ifndef JPEG_FIXSHIFT
#define JPEG_FIXSHIFT 8
  /**< The shift used for converting to and from fixed point.  A higher value
    * here (up to 10 for 32-bit) results in better quality; a lower value
    * (down to 2) results in lesser quality.  Lower values can be somewhat
    * faster depending upon the hardware's clockings for multiplication.
    */
#endif /* JPEG_FIXSHIFT */

#ifndef JPEG_MAXIMUM_SCAN_COMPONENT_FACTORS
#define JPEG_MAXIMUM_SCAN_COMPONENT_FACTORS 10
  /**< The limit of the sum of the multiplied horizontal scaling factors in
    * the components.  For example, if Y is 1x1, Cb is 2x2, and Cr is 2x2,
    * that comes out to (1 * 1 + 2 * 2 + 2 * 2), or 9.  The limit here is
    * what is specified in the standard (B.2.3).
    */
#endif /* JPEG_MAXIMUM_SCAN_COMPONENT_FACTORS */

#ifndef JPEG_FIXED_TYPE
#define JPEG_FIXED_TYPE long int
  /**< The fixed data type.  This requires a minimum size of
    * JPEG_FIXSHIFT plus 12.
    */
#endif /* JPEG_FIXED_TYPE */

/** The markers that can appear in a JPEG stream. */
enum JPEG_Marker
{
  JPEG_Marker_APP0 = 0xFFE0, /**< Reserved application segment 0. */
  JPEG_Marker_APP1 = 0xFFE1, /**< Reserved application segment 1. */
  JPEG_Marker_APP2 = 0xFFE2, /**< Reserved application segment 2. */
  JPEG_Marker_APP3 = 0xFFE3, /**< Reserved application segment 3. */
  JPEG_Marker_APP4 = 0xFFE4, /**< Reserved application segment 4. */
  JPEG_Marker_APP5 = 0xFFE5, /**< Reserved application segment 5. */
  JPEG_Marker_APP6 = 0xFFE6, /**< Reserved application segment 6. */
  JPEG_Marker_APP7 = 0xFFE7, /**< Reserved application segment 7. */
  JPEG_Marker_APP8 = 0xFFE8, /**< Reserved application segment 8. */
  JPEG_Marker_APP9 = 0xFFE9, /**< Reserved application segment 9. */
  JPEG_Marker_APP10 = 0xFFEA, /**< Reserved application segment 10. */
  JPEG_Marker_APP11 = 0xFFEB, /**< Reserved application segment 11. */
  JPEG_Marker_APP12 = 0xFFEC, /**< Reserved application segment 12. */
  JPEG_Marker_APP13 = 0xFFED, /**< Reserved application segment 13. */
  JPEG_Marker_APP14 = 0xFFEE, /**< Reserved application segment 14. */
  JPEG_Marker_APP15 = 0xFFEF, /**< Reserved application segment 15. */
  JPEG_Marker_COM = 0xFFFE, /**< Comment. */
  JPEG_Marker_DHT = 0xFFC4, /**< Define huffman table. */
  JPEG_Marker_DQT = 0xFFDB, /**< Define quantization table(s). */
  JPEG_Marker_DRI = 0xFFDD, /**< Define restart interval. */
  JPEG_Marker_EOI = 0xFFD9, /**< End of image. */
  JPEG_Marker_SOF0 = 0xFFC0, /**< Start of Frame, non-differential, Huffman coding, baseline DCT. */
  JPEG_Marker_SOI = 0xFFD8, /**< Start of image. */
  JPEG_Marker_SOS = 0xFFDA /**< Start of scan. */
};

typedef enum JPEG_Marker JPEG_Marker;
typedef JPEG_FIXED_TYPE JPEG_QuantizationTable [JPEG_DCTSIZE2]; /**< Quantization table elements, in zigzag order, fixed. */

/** Compute the multiplication of two fixed-point values. */
#define JPEG_FIXMUL(A, B) ((A) * (B) >> JPEG_FIXSHIFT)

/** Convert a fixed-point value to an integer. */
#define JPEG_FIXTOI(A) ((A) >> JPEG_FIXSHIFT)

/** Convert an integer to a fixed-point value. */
#define JPEG_ITOFIX(A) ((A) << JPEG_FIXSHIFT)

/** Convert a floating-point value to fixed-point. */
#define JPEG_FTOFIX(A) ((int) ((A) * JPEG_ITOFIX (1)))

/** Convert a fixed-point value to floating-point. */
#define JPEG_FIXTOF(A) ((A) / (float) JPEG_ITOFIX (1))


typedef struct JPEG_HuffmanTable JPEG_HuffmanTable;
typedef struct JPEG_Decoder JPEG_Decoder;
typedef struct JPEG_FrameHeader JPEG_FrameHeader;
typedef struct JPEG_FrameHeader_Component JPEG_FrameHeader_Component;
typedef struct JPEG_ScanHeader JPEG_ScanHeader;
typedef struct JPEG_ScanHeader_Component JPEG_ScanHeader_Component;

/** A huffman table. */
struct JPEG_HuffmanTable
{
  const unsigned char *huffval; /**< Pointer to values in the table (256 entries). */
  int maxcode [16]; /**< The maximum code for each length - 1. */
  const unsigned char *valptr [16]; /**< Items are subtracted by mincode and then indexed into huffval. */
  
  unsigned char look_nbits [256]; /**< The lookahead buffer lengths. */
  unsigned char look_sym [256]; /**< The lookahead buffer values. */
};

/** An image component in the frame. */
struct JPEG_FrameHeader_Component
{
  unsigned char selector; /**< Component identifier, must be unique amongst the identifiers (C). */
  unsigned char horzFactor; /**< Horizontal sampling factor. */
  unsigned char vertFactor; /**< Vertical sampling factor. */
  unsigned char quantTable; /**< Quantization table destination selector. */
};

/** The frame header state. */
struct JPEG_FrameHeader
{
  JPEG_Marker marker; /**< The marker that began this frame header, one of JPEG_Marker_SOFn. */
  int encoding; /**< 0 for Huffman coding, 1 for arithmetic coding. */
  char differential; /**< Differential (1) or non-differential (0). */
  
  unsigned char precision; /**< Sample precision - precision in bits for the samples of the components in the frame. */
  unsigned short height; /**< Maximum number of lines in the source image, equal to the number of lines in the component with the maximum number of vertical samples.  0 indicates that the number of lines shall be defined by the DNL marker and parameters at the end of the first scan. */
  unsigned short width; /**< Number of samples per line in the source image, equal to the number of samples per line in the component with the maximum number of horizontal samples. */
  JPEG_FrameHeader_Component componentList [JPEG_MAXIMUM_COMPONENTS]; /**< Components. */
  int componentCount; /**< Number of components. */
};

/** A component involved in this scan. */
struct JPEG_ScanHeader_Component
{
  unsigned char selector; /**< Selector index corresponding to one specified in the frame header (Csj). */
  unsigned char dcTable; /**< DC entropy coding table destination selector (Tdj). */
  unsigned char acTable; /**< AC entropy coding table destination selector (Taj). */
};

/** Scan header state. */
struct JPEG_ScanHeader
{
  JPEG_ScanHeader_Component componentList [JPEG_MAXIMUM_COMPONENTS]; /**< Components involved in this scan. */
  int componentCount; /**< Number of components involved in this scan. */
  unsigned char spectralStart; /**< In DCT modes of operation, the first DCT coefficient in each block in zig-zag order which shall be coded in the scan (Ss).  For sequential DCT this is zero. */
  unsigned char spectralEnd; /**< Specify the last DCT coefficient in each block in zig-zag order which shall be coded in the scan. */
  unsigned char successiveApproximationBitPositionHigh; /**< (Ah). */
  unsigned char successiveApproximationBitPositionLow; /**< (Al). */
};

/** The complete decoder state. */
struct JPEG_Decoder
{
  const unsigned char *acTables [4]; /**< The AC huffman table slots. */
  const unsigned char *dcTables [4]; /**< The DC huffman table slots. */
  JPEG_QuantizationTable quantTables [4]; /**< The quantization table slots. */
  unsigned int restartInterval; /**< Number of MCU in the restart interval (Ri). */
  JPEG_FrameHeader frame; /**< Current frame. */
  JPEG_ScanHeader scan; /**< Current scan. */
};

/** Start reading bits. */
#define JPEG_BITS_START() \
  unsigned int bits_left = 0; \
  unsigned long int bits_data = 0
  
/** Rewind any bytes that have not been read from and reset the state. */
#define JPEG_BITS_REWIND() \
  do { \
    int count = bits_left >> 3; \
    \
    while (count --) \
    { \
      data --; \
      if (data [-1] == 0xFF) \
        data --; \
    } \
    \
    bits_left = 0; \
    bits_data = 0; \
  } while (0)
  
/** Fill the buffer. */
#define JPEG_BITS_CHECK() \
  do { \
    while (bits_left < 32 - 7) \
    { \
      bits_data = (bits_data << 8) | (*data ++); \
      if (data [-1] == 0xFF) \
        data ++; \
      bits_left += 8; \
    } \
  } while (0)
   
/** Return and consume a number of bits. */
#define JPEG_BITS_GET(COUNT) \
  ((bits_data >> (bits_left -= (COUNT))) & ((1 << (COUNT)) - 1))
  
/** Return a number of bits without consuming them. */
#define JPEG_BITS_PEEK(COUNT) \
  ((bits_data >> (bits_left - (COUNT))) & ((1 << (COUNT)) - 1))
  
/** Drop a number of bits from the stream. */
#define JPEG_BITS_DROP(COUNT) \
  (bits_left -= (COUNT))

/** Read a single unsigned char from the current bit-stream by using the provided table. */
#define JPEG_HuffmanTable_Decode(TABLE, OUT) \
  do { \
    int bitcount, result; \
    \
    result = JPEG_BITS_PEEK (8); \
    \
    if ((bitcount = (TABLE)->look_nbits [result]) != 0) \
    { \
      JPEG_BITS_DROP (bitcount); \
      result = (TABLE)->look_sym [result]; \
    } \
    else \
    { \
      int i = 7; \
      \
      JPEG_BITS_DROP (8); \
      do result = (result << 1) | JPEG_BITS_GET (1); \
      while (result > (TABLE)->maxcode [++ i]); \
      \
      result = (TABLE)->valptr [i] [result]; \
    } \
    \
    (OUT) = result; \
  } while (0)

extern const unsigned char JPEG_ToZigZag [JPEG_DCTSIZE2]; /* Converts row-major indices to zig-zagged order. */
extern const unsigned char JPEG_FromZigZag [JPEG_DCTSIZE2]; /* Converts zig-zagged indices to row-major order. */
extern const JPEG_FIXED_TYPE JPEG_AANScaleFactor [JPEG_DCTSIZE2]; /* AA&N scaling factors for quantisation in fixed point. */
extern const unsigned char JPEG_ComponentRange [32 * 3]; /* A limited component clamp that keeps values in the 0..31 range if incremented by 32. */

/** Return whether this data matches as a JPEG input stream.  You only need
  * to read four bytes.
  */
  
extern int JPEG_Match (const unsigned char *data, int length);

/** Read a FrameHeader segment (SOFn) and store the new data pointer in
  * *data.  Returns true on success and false on failure (failure isn't
  * possible if JPEG_DEBUG is reset).
  */

extern int JPEG_FrameHeader_Read (JPEG_FrameHeader *frame, const unsigned char **data, JPEG_Marker marker);

/** Read a HuffmanTable segment (DHT) and store the new data pointer in
  * *data.  Returns true on success and false on failure (failure isn't
  * possible if JPEG_DEBUG is reset).
  */
  
extern int JPEG_HuffmanTable_Read (JPEG_HuffmanTable *table, const unsigned char **data);

/** Skip a HuffmanTable segment (DHT) and store the new data pointer in
  * *data on success.  Returns true on success and false on failure (failure
  * isn't possible if JPEG_DEBUG is reset).
  */
  
extern int JPEG_HuffmanTable_Skip (const unsigned char **data);

/** Read a ScanHeader segment (SOS) and store the new data pointer in
  * *data.  Returns true on success and false on failure (failure isn't
  * possible if JPEG_DEBUG is reset).
  */
  
extern int JPEG_ScanHeader_Read (JPEG_ScanHeader *scan, const unsigned char **data);

/** Read all headers up to the start of the image and store the new data
  * pointer in *data.  Returns true on success and false on failure (failure
  * isn't possible if JPEG_DEBUG is reset).
  */
  
extern int JPEG_Decoder_ReadHeaders (JPEG_Decoder *decoder, const unsigned char **data);

/** Read the entire image from the *data value and then store the new data pointer.
  * Returns true on success and false on failure (failure isn't possible if
  * JPEG_DEBUG is reset).
  */
  
extern int JPEG_Decoder_ReadImage (JPEG_Decoder *decoder, const unsigned char **data, signed char *out, int outWidth, int outHeight);

/** Perform a 2D inverse DCT computation on the input.
  *
  * @param zz The coefficients to process, JPEG_DCTSIZE2 in length.  The
  *   contents will be destroyed in the computations.
  * @param chunk The chunk to store the results in, nominally from -64 to 63,
  *   although some error is expected.
  * @param chunkStride The number of values in a row for the chunk array.
  */

extern void JPEG_IDCT (JPEG_FIXED_TYPE *zz, signed char *chunk, int chunkStride);

/** Create a decompressor, read the headers from the provided data, and then
  * read the image into the buffer given.  Returns true on success and false on
  * failure (failure isn't possible if JPEG_DEBUG is reset).
  */
  
extern int JPEG_DecompressImage (const unsigned char *data, signed char *out, int outWidth, int outHeight);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -