archived-mpp/mpp/hal/vpu/jpege/hal_jpege_hdr.c
Herman Chen 2b35cee0ce [mpp_log]: Add more log helper function
1. Move mpp_log.h to inc for external user.
2. Add mpp_debug.h for mpp internal logging.
3. Fix some warning.
4. Add log level setup function.
5. Check env log_level value in mpp_get_log_level call.

NOTE:
1. mpp internal module should use mpp_debug.h and mpp external user
should use mpp_log.h
2. Use mpp_get_log_level to update mpp_log_level when the env changed.

Change-Id: I90a55a02a72db177533013280dfe111ca3479229
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
2022-05-20 11:42:10 +08:00

938 lines
23 KiB
C

/*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* 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 "mpp_mem.h"
#include "mpp_debug.h"
#include "mpp_common.h"
#include "hal_jpege_hdr.h"
#define MAX_NUMBER_OF_COMPONENTS 3
/* JPEG markers, table B.1 */
enum {
SOI = 0xFFD8, /* Start of Image */
DQT = 0xFFDB, /* Define Quantization Table(s) */
SOF0 = 0xFFC0, /* Start of Frame */
DRI = 0xFFDD, /* Define Restart Interval */
RST0 = 0xFFD0, /* Restart marker 0 */
RST1 = 0xFFD1, /* Restart marker 1 */
RST2 = 0xFFD2, /* Restart marker 2 */
RST3 = 0xFFD3, /* Restart marker 3 */
RST4 = 0xFFD4, /* Restart marker 4 */
RST5 = 0xFFD5, /* Restart marker 5 */
RST6 = 0xFFD6, /* Restart marker 6 */
RST7 = 0xFFD7, /* Restart marker 7 */
DHT = 0xFFC4, /* Define Huffman Table(s) */
SOS = 0xFFDA, /* Start of Scan */
EOI = 0xFFD9, /* End of Image */
APP0 = 0xFFE0, /* APP0 Marker */
APP7 = 0xFFE7, /* APP7 Marker */
COM = 0xFFFE /* Comment marker */
};
enum {
JPEGE_NO_UNITS = 0,
JPEGE_DOTS_PER_INCH = 1,
JPEGE_DOTS_PER_CM = 2
};
enum {
JPEGE_SINGLE_MARKER,
JPEGE_MULTI_MARKER
};
static const RK_U8 zigzag[64] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
/* Mjpeg quantization tables levels 0-10 */
static const RK_U8 qtable_y[11][64] = {
{
80, 56, 50, 80, 120, 200, 248, 248,
60, 60, 72, 96, 136, 248, 248, 248,
72, 68, 80, 120, 200, 248, 248, 248,
72, 88, 112, 152, 248, 248, 248, 248,
92, 112, 192, 248, 248, 248, 248, 248,
120, 176, 248, 248, 248, 248, 248, 248,
152, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248
},
{
40, 28, 25, 40, 60, 100, 128, 160,
30, 30, 36, 48, 68, 152, 152, 144,
36, 34, 40, 60, 100, 144, 176, 144,
36, 44, 56, 76, 128, 224, 200, 160,
46, 56, 96, 144, 176, 248, 248, 200,
60, 88, 144, 160, 208, 248, 248, 232,
124, 160, 200, 224, 248, 248, 248, 248,
184, 232, 240, 248, 248, 248, 248, 248
},
{
27, 18, 17, 27, 40, 68, 88, 104,
20, 20, 23, 32, 44, 96, 100, 92,
23, 22, 27, 40, 68, 96, 116, 96,
23, 28, 38, 48, 88, 144, 136, 104,
30, 38, 62, 96, 116, 184, 176, 128,
40, 58, 92, 108, 136, 176, 192, 160,
84, 108, 136, 144, 176, 208, 200, 168,
120, 160, 160, 168, 192, 168, 176, 168
},
{
20, 14, 13, 20, 30, 50, 64, 76,
15, 15, 18, 24, 34, 76, 76, 72,
18, 16, 20, 30, 50, 72, 88, 72,
18, 21, 28, 36, 64, 112, 100, 80,
23, 28, 46, 72, 88, 136, 136, 96,
30, 44, 72, 80, 104, 136, 144, 116,
62, 80, 100, 112, 136, 152, 152, 128,
92, 116, 120, 124, 144, 128, 136, 124
},
{
16, 11, 10, 16, 24, 40, 52, 62,
12, 12, 14, 19, 26, 58, 60, 56,
14, 13, 16, 24, 40, 58, 72, 56,
14, 17, 22, 29, 52, 88, 80, 62,
18, 22, 38, 56, 68, 112, 104, 80,
24, 36, 56, 64, 84, 104, 116, 92,
50, 64, 80, 88, 104, 124, 120, 104,
72, 92, 96, 100, 124, 100, 104, 100
},
{
13, 9, 8, 13, 19, 32, 42, 50,
10, 10, 11, 15, 21, 46, 48, 44,
11, 10, 13, 19, 32, 46, 56, 46,
11, 14, 18, 23, 42, 72, 64, 50,
14, 18, 30, 46, 54, 88, 84, 62,
19, 28, 44, 52, 68, 84, 92, 76,
40, 52, 62, 72, 84, 100, 96, 84,
58, 76, 76, 80, 100, 80, 84, 80
},
{
10, 7, 6, 10, 14, 24, 31, 38,
7, 7, 8, 11, 16, 36, 36, 34,
8, 8, 10, 14, 24, 34, 42, 34,
8, 10, 13, 17, 32, 52, 48, 38,
11, 13, 22, 34, 42, 68, 62, 46,
14, 21, 34, 38, 50, 62, 68, 56,
29, 38, 48, 52, 62, 76, 72, 62,
44, 56, 58, 60, 68, 60, 62, 60
},
{
6, 4, 4, 6, 10, 16, 20, 24,
5, 5, 6, 8, 10, 23, 24, 22,
6, 5, 6, 10, 16, 23, 28, 22,
6, 7, 9, 12, 20, 36, 32, 25,
7, 9, 15, 22, 27, 44, 42, 31,
10, 14, 22, 26, 32, 42, 46, 38,
20, 26, 31, 36, 42, 48, 48, 40,
29, 38, 38, 40, 46, 40, 42, 40
},
{
3, 2, 2, 3, 5, 8, 10, 12,
2, 2, 3, 4, 5, 12, 12, 11,
3, 3, 3, 5, 8, 11, 14, 11,
3, 3, 4, 6, 10, 17, 16, 12,
4, 4, 7, 11, 14, 22, 21, 15,
5, 7, 11, 13, 16, 21, 23, 18,
10, 13, 16, 17, 21, 24, 24, 20,
14, 18, 19, 20, 22, 20, 21, 20
},
{
1, 1, 1, 1, 2, 3, 3, 4,
1, 1, 1, 1, 2, 4, 4, 4,
1, 1, 1, 2, 3, 4, 5, 4,
1, 1, 1, 2, 3, 6, 5, 4,
1, 1, 2, 4, 5, 7, 7, 5,
2, 2, 4, 4, 5, 7, 8, 6,
3, 4, 5, 6, 7, 8, 8, 7,
5, 6, 6, 7, 7, 7, 7, 7
},
{
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
}
};
static const RK_U8 qtable_c[11][64] = {
{
88, 92, 120, 240, 248, 248, 248, 248,
92, 108, 136, 248, 248, 248, 248, 248,
120, 136, 248, 248, 248, 248, 248, 248,
240, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248
},
{
44, 46, 60, 120, 248, 248, 248, 248,
46, 54, 68, 168, 248, 248, 248, 248,
60, 66, 144, 248, 248, 248, 248, 248,
120, 168, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248
},
{
28, 30, 40, 80, 168, 168, 168, 168,
30, 36, 44, 112, 168, 168, 168, 168,
40, 44, 96, 168, 168, 168, 168, 168,
80, 112, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168
},
{
21, 23, 30, 60, 124, 124, 124, 124,
23, 26, 34, 84, 124, 124, 124, 124,
30, 34, 72, 124, 124, 124, 124, 124,
60, 84, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124
},
{
17, 18, 24, 48, 100, 100, 100, 100,
18, 21, 26, 68, 100, 100, 100, 100,
24, 26, 56, 100, 100, 100, 100, 100,
48, 68, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100
},
{
14, 14, 19, 38, 80, 80, 80, 80,
14, 17, 21, 54, 80, 80, 80, 80,
19, 21, 46, 80, 80, 80, 80, 80,
38, 54, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80
},
{
10, 11, 14, 28, 60, 60, 60, 60,
11, 13, 16, 40, 60, 60, 60, 60,
14, 16, 34, 60, 60, 60, 60, 60,
28, 40, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 60, 60, 60, 60
},
{
7, 7, 10, 19, 40, 40, 40, 40,
7, 8, 10, 26, 40, 40, 40, 40,
10, 10, 22, 40, 40, 40, 40, 40,
19, 26, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40
},
{
3, 4, 5, 9, 20, 20, 20, 20,
4, 4, 5, 13, 20, 20, 20, 20,
5, 5, 11, 20, 20, 20, 20, 20,
9, 13, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20
},
{
1, 1, 2, 3, 7, 7, 7, 7,
1, 1, 2, 4, 7, 7, 7, 7,
2, 2, 4, 7, 7, 7, 7, 7,
3, 4, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7
},
{
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
}
};
typedef struct {
RK_U32 Ci[MAX_NUMBER_OF_COMPONENTS];
RK_U32 Hi[MAX_NUMBER_OF_COMPONENTS];
RK_U32 Vi[MAX_NUMBER_OF_COMPONENTS];
RK_U32 Tqi[MAX_NUMBER_OF_COMPONENTS];
} JpegeColorInfo;
static const JpegeColorInfo color_info[2] = {
{
/* YUV420 */
{ 1, 2, 3, },
{ 2, 1, 1, },
{ 2, 1, 1, },
{ 0, 1, 1, },
},
{
/* YUV422 */
{ 1, 2, 3, },
{ 2, 1, 1, },
{ 1, 1, 1, },
{ 0, 1, 1, },
},
};
typedef struct {
RK_U32 val_y;
RK_U32 val_c;
} JpegeHuffmanTable;
static const JpegeHuffmanTable dc_li[16] = {
{0x00, 0x00},
{0x01, 0x03},
{0x05, 0x01},
{0x01, 0x01},
{0x01, 0x01},
{0x01, 0x01},
{0x01, 0x01},
{0x01, 0x01},
{0x01, 0x01},
{0x00, 0x01},
{0x00, 0x01},
{0x00, 0x00},
{0x00, 0x00},
{0x00, 0x00},
{0x00, 0x00},
{0x00, 0x00}
};
static const JpegeHuffmanTable dc_vij[12] = {
{0x00, 0x00},
{0x01, 0x01},
{0x02, 0x02},
{0x03, 0x03},
{0x04, 0x04},
{0x05, 0x05},
{0x06, 0x06},
{0x07, 0x07},
{0x08, 0x08},
{0x09, 0x09},
{0x0A, 0x0A},
{0x0B, 0x0B},
};
static const JpegeHuffmanTable ac_li[16] = {
{0x00, 0x00},
{0x02, 0x02},
{0x01, 0x01},
{0x03, 0x02},
{0x03, 0x04},
{0x02, 0x04},
{0x04, 0x03},
{0x03, 0x04},
{0x05, 0x07},
{0x05, 0x05},
{0x04, 0x04},
{0x04, 0x04},
{0x00, 0x00},
{0x00, 0x01},
{0x01, 0x02},
{0x7D, 0x77}
};
static const JpegeHuffmanTable ac_vij[162] = {
{0x01, 0x00},
{0x02, 0x01},
{0x03, 0x02},
{0x00, 0x03},
{0x04, 0x11},
{0x11, 0x04},
{0x05, 0x05},
{0x12, 0x21},
{0x21, 0x31},
{0x31, 0x06},
{0x41, 0x12},
{0x06, 0x41},
{0x13, 0x51},
{0x51, 0x07},
{0x61, 0x61},
{0x07, 0x71},
{0x22, 0x13},
{0x71, 0x22},
{0x14, 0x32},
{0x32, 0x81},
{0x81, 0x08},
{0x91, 0x14},
{0xA1, 0x42},
{0x08, 0x91},
{0x23, 0xA1},
{0x42, 0xB1},
{0xB1, 0xC1},
{0xC1, 0x09},
{0x15, 0x23},
{0x52, 0x33},
{0xD1, 0x52},
{0xF0, 0xF0},
{0x24, 0x15},
{0x33, 0x62},
{0x62, 0x72},
{0x72, 0xD1},
{0x82, 0x0A},
{0x09, 0x16},
{0x0A, 0x24},
{0x16, 0x34},
{0x17, 0xE1},
{0x18, 0x25},
{0x19, 0xF1},
{0x1A, 0x17},
{0x25, 0x18},
{0x26, 0x19},
{0x27, 0x1A},
{0x28, 0x26},
{0x29, 0x27},
{0x2A, 0x28},
{0x34, 0x29},
{0x35, 0x2A},
{0x36, 0x35},
{0x37, 0x36},
{0x38, 0x37},
{0x39, 0x38},
{0x3A, 0x39},
{0x43, 0x3A},
{0x44, 0x43},
{0x45, 0x44},
{0x46, 0x45},
{0x47, 0x46},
{0x48, 0x47},
{0x49, 0x48},
{0x4A, 0x49},
{0x53, 0x4A},
{0x54, 0x53},
{0x55, 0x54},
{0x56, 0x55},
{0x57, 0x56},
{0x58, 0x57},
{0x59, 0x58},
{0x5A, 0x59},
{0x63, 0x5A},
{0x64, 0x63},
{0x65, 0x64},
{0x66, 0x65},
{0x67, 0x66},
{0x68, 0x67},
{0x69, 0x68},
{0x6A, 0x69},
{0x73, 0x6A},
{0x74, 0x73},
{0x75, 0x74},
{0x76, 0x75},
{0x77, 0x76},
{0x78, 0x77},
{0x79, 0x78},
{0x7A, 0x79},
{0x83, 0x7A},
{0x84, 0x82},
{0x85, 0x83},
{0x86, 0x84},
{0x87, 0x85},
{0x88, 0x86},
{0x89, 0x87},
{0x8A, 0x88},
{0x92, 0x89},
{0x93, 0x8A},
{0x94, 0x92},
{0x95, 0x93},
{0x96, 0x94},
{0x97, 0x95},
{0x98, 0x96},
{0x99, 0x97},
{0x9A, 0x98},
{0xA2, 0x99},
{0xA3, 0x9A},
{0xA4, 0xA2},
{0xA5, 0xA3},
{0xA6, 0xA4},
{0xA7, 0xA5},
{0xA8, 0xA6},
{0xA9, 0xA7},
{0xAA, 0xA8},
{0xB2, 0xA9},
{0xB3, 0xAA},
{0xB4, 0xB2},
{0xB5, 0xB3},
{0xB6, 0xB4},
{0xB7, 0xB5},
{0xB8, 0xB6},
{0xB9, 0xB7},
{0xBA, 0xB8},
{0xC2, 0xB9},
{0xC3, 0xBA},
{0xC4, 0xC2},
{0xC5, 0xC3},
{0xC6, 0xC4},
{0xC7, 0xC5},
{0xC8, 0xC6},
{0xC9, 0xC7},
{0xCA, 0xC8},
{0xD2, 0xC9},
{0xD3, 0xCA},
{0xD4, 0xD2},
{0xD5, 0xD3},
{0xD6, 0xD4},
{0xD7, 0xD5},
{0xD8, 0xD6},
{0xD9, 0xD7},
{0xDA, 0xD8},
{0xE1, 0xD9},
{0xE2, 0xDA},
{0xE3, 0xE2},
{0xE4, 0xE3},
{0xE5, 0xE4},
{0xE6, 0xE5},
{0xE7, 0xE6},
{0xE8, 0xE7},
{0xE9, 0xE8},
{0xEA, 0xE9},
{0xF1, 0xEA},
{0xF2, 0xF2},
{0xF3, 0xF3},
{0xF4, 0xF4},
{0xF5, 0xF5},
{0xF6, 0xF6},
{0xF7, 0xF7},
{0xF8, 0xF8},
{0xF9, 0xF9},
{0xFA, 0xFA}
};
typedef struct {
RK_U8 *buffer; /* Pointer to first byte of stream */
RK_U8 *stream; /* Pointer to next byte of stream */
RK_U32 size; /* Byte size of stream buffer */
RK_U32 byteCnt; /* Byte counter */
RK_U32 bitCnt; /* Bit counter */
RK_U32 byteBuffer; /* Byte buffer */
RK_U32 bufferedBits; /* Amount of bits in byte buffer, [0-7] */
} JpegeBitsImpl;
void jpege_bits_init(JpegeBits *ctx)
{
JpegeBitsImpl *impl = mpp_malloc(JpegeBitsImpl, 1);
*ctx = impl;
}
void jpege_bits_deinit(JpegeBits ctx)
{
if (ctx)
mpp_free(ctx);
}
void jpege_bits_setup(JpegeBits ctx, RK_U8 *buf, RK_S32 size)
{
JpegeBitsImpl *impl = (JpegeBitsImpl *)ctx;
impl->buffer = buf;
impl->stream = buf;
impl->size = size;
impl->byteCnt = 0;
impl->bitCnt = 0;
impl->byteBuffer = 0;
impl->bufferedBits = 0;
}
void jpege_bits_put(JpegeBits ctx, RK_U32 value, RK_S32 number)
{
JpegeBitsImpl *impl = (JpegeBitsImpl *)ctx;
RK_U32 bits;
RK_U32 byteBuffer = impl->byteBuffer;
RK_U8 *stream = impl->stream;
/* Debug: value is too big */
mpp_assert(value < ((RK_U32) 1 << number));
mpp_assert(number < 25);
bits = number + impl->bufferedBits;
value <<= (32 - bits);
byteBuffer = (((RK_U32) stream[0]) << 24) | value;
while (bits > 7) {
*stream = (RK_U8) (byteBuffer >> 24);
bits -= 8;
byteBuffer <<= 8;
stream++;
impl->byteCnt++;
}
stream[0] = (RK_U8) (byteBuffer >> 24);
impl->stream = stream;
impl->bitCnt += number;
impl->byteBuffer = byteBuffer;
impl->bufferedBits = (RK_U8) bits;
}
void jpege_seek_bits(JpegeBits ctx, RK_S32 len)
{
JpegeBitsImpl *impl = (JpegeBitsImpl*)ctx;
RK_U32 bits = len;
RK_U8 *stream = impl->stream;
mpp_assert(bits < impl->size);
while (bits > 7) {
stream++;
impl->byteCnt++;
bits -= 8;
}
impl->stream = stream;
impl->bitCnt += len;
impl->byteBuffer = (RK_U32)stream[0];
impl->bufferedBits = (RK_U8) bits;
}
void jpege_bits_align_byte(JpegeBits ctx)
{
JpegeBitsImpl *impl = (JpegeBitsImpl *)ctx;
if (impl->bitCnt & 7)
jpege_bits_put(ctx, 0, 8 - (impl->bitCnt & 7));
}
RK_U8 *jpege_bits_get_buf(JpegeBits ctx)
{
JpegeBitsImpl *impl = (JpegeBitsImpl *)ctx;
return impl->buffer;
}
RK_S32 jpege_bits_get_bitpos(JpegeBits ctx)
{
JpegeBitsImpl *impl = (JpegeBitsImpl *)ctx;
return impl->bitCnt;
}
RK_S32 jpege_bits_get_bytepos(JpegeBits ctx)
{
JpegeBitsImpl *impl = (JpegeBitsImpl *)ctx;
return impl->byteCnt;
}
static void write_jpeg_comment_header(JpegeBits *bits, JpegeSyntax *syntax)
{
RK_U32 i;
RK_U8 *data = syntax->comment_data;
RK_U32 length = syntax->comment_length;
/* COM */
jpege_bits_put(bits, COM, 16);
/* Lc */
jpege_bits_put(bits, 2 + length, 16);
for (i = 0; i < length; i++) {
/* COM data */
jpege_bits_put(bits, data[i], 8);
}
}
static void write_jpeg_dqt_header(JpegeBits *bits, const RK_U8 *qtables[2])
{
RK_S32 i;
const RK_U8 *qtable = qtables[0];
/* DQT */
jpege_bits_put(bits, DQT, 16);
/* Lq */
jpege_bits_put(bits, 2 + 65, 16);
/* Pq */
jpege_bits_put(bits, 0, 4);
/* Tq */
jpege_bits_put(bits, 0, 4);
for (i = 0; i < 64; i++) {
/* Qk table 0 */
jpege_bits_put(bits, qtable[zigzag[i]], 8);
}
/* DQT */
jpege_bits_put(bits, DQT, 16);
/* Lq */
jpege_bits_put(bits, 2 + 65, 16);
/* Pq */
jpege_bits_put(bits, 0, 4);
/* Tq */
jpege_bits_put(bits, 1, 4);
qtable = qtables[1];
for (i = 0; i < 64; i++) {
/* Qk table 1 */
jpege_bits_put(bits, qtable[zigzag[i]], 8);
}
}
static void write_jpeg_SOFO_header(JpegeBits *bits, JpegeSyntax *syntax)
{
RK_S32 i;
RK_U32 width = syntax->width;
RK_U32 height = syntax->height;
const JpegeColorInfo *info = &color_info[0];
/* SOF0 */
jpege_bits_put(bits, SOF0, 16);
/* Lf */
jpege_bits_put(bits, (8 + 3 * 3), 16);
/* P */
jpege_bits_put(bits, 8, 8);
/* Y */
jpege_bits_put(bits, height, 16);
/* X */
jpege_bits_put(bits, width, 16);
/* Nf */
jpege_bits_put(bits, 3, 8);
/* NOTE: only output 420 bits */
for (i = 0; i < 3; i++) {
/* Ci */
jpege_bits_put(bits, info->Ci[i], 8);
/* Hi */
jpege_bits_put(bits, info->Hi[i], 4);
/* Vi */
jpege_bits_put(bits, info->Vi[i], 4);
/* Tqi */
jpege_bits_put(bits, info->Tqi[i], 8);
}
}
static void write_jpeg_dht_header(JpegeBits *bits)
{
RK_S32 i;
/* DHT */
jpege_bits_put(bits, DHT, 16);
/* Huffman table for luminance DC components */
/* Lh */
jpege_bits_put(bits, 2 + ((17 * 1) + ((1 * 12))), 16);
/* TC */
jpege_bits_put(bits, 0, 4);
/* TH */
jpege_bits_put(bits, 0, 4);
for (i = 0; i < 16; i++) {
/* Dc_Li */
jpege_bits_put(bits, dc_li[i].val_y, 8);
}
for (i = 0; i < 12; i++) {
/* Dc_Vij */
jpege_bits_put(bits, dc_vij[i].val_y, 8);
}
/* DHT */
jpege_bits_put(bits, DHT, 16);
/* Huffman table for luminance AC components */
/* Lh */
jpege_bits_put(bits, 2 + ((17 * 1) + ((1 * 162))), 16);
/* TC */
jpege_bits_put(bits, 1, 4);
/* TH */
jpege_bits_put(bits, 0, 4);
for (i = 0; i < 16; i++) {
/* Ac_Li */
jpege_bits_put(bits, ac_li[i].val_y, 8);
}
for (i = 0; i < 162; i++) {
/* Ac_Vij */
jpege_bits_put(bits, ac_vij[i].val_y, 8);
}
/* Huffman table for chrominance DC components */
/* DHT */
jpege_bits_put(bits, DHT, 16);
/* Lh */
jpege_bits_put(bits, 2 + ((17 * 1) + ((1 * 12))), 16);
/* TC */
jpege_bits_put(bits, 0, 4);
/* TH */
jpege_bits_put(bits, 1, 4);
for (i = 0; i < 16; i++) {
/* Dc_Li */
jpege_bits_put(bits, dc_li[i].val_c, 8);
}
for (i = 0; i < 12; i++) {
/* Dc_Vij */
jpege_bits_put(bits, dc_vij[i].val_c, 8);
}
/* Huffman table for chrominance AC components */
/* DHT */
jpege_bits_put(bits, DHT, 16);
/* Lh */
jpege_bits_put(bits, 2 + ((17 * 1) + ((1 * 162))), 16);
/* TC */
jpege_bits_put(bits, 1, 4);
/* TH */
jpege_bits_put(bits, 1, 4);
for (i = 0; i < 16; i++) {
/* Ac_Li */
jpege_bits_put(bits, ac_li[i].val_c, 8);
}
for (i = 0; i < 162; i++) {
/* Ac_Vij */
jpege_bits_put(bits, ac_vij[i].val_c, 8);
}
}
static void write_jpeg_sos_header(JpegeBits *bits)
{
RK_U32 i;
RK_U32 Ns = 3;
RK_U32 Ls = (6 + (2 * Ns));
/* SOS */
jpege_bits_put(bits, SOS, 16);
/* Ls */
jpege_bits_put(bits, Ls, 16);
/* Ns */
jpege_bits_put(bits, Ns, 8);
for (i = 0; i < Ns; i++) {
/* Csj */
jpege_bits_put(bits, i + 1, 8);
if (i == 0) {
/* Tdj */
jpege_bits_put(bits, 0, 4);
/* Taj */
jpege_bits_put(bits, 0, 4);
} else {
/* Tdj */
jpege_bits_put(bits, 1, 4);
/* Taj */
jpege_bits_put(bits, 1, 4);
}
}
/* Ss */
jpege_bits_put(bits, 0, 8);
/* Se */
jpege_bits_put(bits, 63, 8);
/* Ah */
jpege_bits_put(bits, 0, 4);
/* Al */
jpege_bits_put(bits, 0, 4);
}
void write_jpeg_RestartInterval(JpegeBits *bits, JpegeSyntax *syntax)
{
if (syntax->restart_ri) {
jpege_bits_put(bits, 0xFFDD, 16);
jpege_bits_put(bits, 4, 16);
jpege_bits_put(bits, syntax->restart_ri, 16);
}
}
MPP_RET write_jpeg_header(JpegeBits *bits, JpegeSyntax *syntax, const RK_U8 *qtables[2])
{
/* Com header */
if (syntax->comment_length)
write_jpeg_comment_header(bits, syntax);
/* Quant header */
if (!qtables[0]) {
if (syntax->qtable_y)
qtables[0] = syntax->qtable_y;
else
qtables[0] = qtable_y[syntax->quality];
}
if (!qtables[1]) {
if (syntax->qtable_c)
qtables[1] = syntax->qtable_c;
else
qtables[1] = qtable_c[syntax->quality];
}
write_jpeg_dqt_header(bits, qtables);
/* Frame header */
write_jpeg_SOFO_header(bits, syntax);
/* Do NOT have Restart interval */
write_jpeg_RestartInterval(bits, syntax);
/* Huffman header */
write_jpeg_dht_header(bits);
/* Scan header */
write_jpeg_sos_header(bits);
jpege_bits_align_byte(bits);
return MPP_OK;
}