1/*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 *    Elaine Wang <elaine.wang@intel.com>
27 *
28 */
29
30/*#include <string.h>*/
31#include <stdio.h>
32
33#include <pnw_hostcode.h>
34#include <pnw_hostjpeg.h>
35#include "psb_drv_debug.h"
36
37#define TRACK_FREE(ptr)                 free(ptr)
38#define TRACK_MALLOC(ptr)               malloc(ptr)
39#define TRACK_DEVICE_MEMORY_INIT
40#define TRACK_DEVICE_MEMORY_SHOW
41#define TIMER_INIT
42#define TIMER_START(...)
43#define TIMER_END(...)
44#define TIMER_CLOSE
45#define TIMER_CAPTURE(...)
46
47
48//#include <stdio.h>
49//#include <memory.h>
50//#include <stdlib.h>
51//#include <stdlib.h>
52//#include "malloc.h"
53//#include "mtxmain.h"
54
55//#include "mtxccb.h"
56//#include "topaz_tests.h"
57//#include "mvea_regs.h"
58//#include "mtx_regs.h"
59//#include "defs.h"
60//#include "mtxencode.h"
61//#include "topaz_vlc_regs.h"
62//#include "mtxheader.h"
63//#include "apiinternal.h"
64
65//#ifdef FIXME
66//extern void JPEGInitialiseHardware();
67//#endif
68
69#define JPEG_INCLUDE_NONAPI 1
70
71
72
73/////////////////////////////////////////////////////////////////////////////////////
74// BMP Reading Header Stuff
75/////////////////////////////////////////////////////////////////////////////////////
76
77
78const IMG_UINT8 gQuantLuma[QUANT_TABLE_SIZE_BYTES] = {
79    16, 11, 10, 16, 24, 40, 51, 61,
80    12, 12, 14, 19, 26, 58, 60, 55,
81    14, 13, 16, 24, 40, 57, 69, 56,
82    14, 17, 22, 29, 51, 87, 80, 62,
83    18, 22, 37, 56, 68, 109, 103, 77,
84    24, 35, 55, 64, 81, 104, 113, 92,
85    49, 64, 78, 87, 103, 121, 120, 101,
86    72, 92, 95, 98, 112, 100, 103, 99
87};
88
89/*const IMG_UINT8 DEBUG_gQuantLumaForCoverage[QUANT_TABLE_SIZE_BYTES] =
90{
91    16, 17, 21, 22, 30, 31, 22, 45,
92    18, 20, 23, 29, 32, 29, 44, 46,
93    19, 24, 28, 33, 36, 43, 47, 58,
94    25, 27, 34, 29, 42, 48, 57, 59,
95    26, 34, 37, 41, 49, 56 , 60 , 67,
96    36, 35, 40, 50, 55, 61 , 66 , 68,
97    37, 39, 51, 54, 62 , 65 , 69 , 72 ,
98    38, 52, 53, 63, 64 , 70 , 71 , 73
99};*/
100
101int DEBUG_giUsegQuantLumaForCoverageTable = 0;
102
103/*****************************************************************************/
104/*  \brief   gQuantChroma                                                    */
105/*                                                                           */
106/*  Contains the data that needs to be sent in the marker segment of an      */
107/*  interchange format JPEG stream or an abbreviated format table            */
108/*  specification data stream.                                               */
109/*  Quantizer table for the chrominance component                            */
110/*****************************************************************************/
111const IMG_UINT8 gQuantChroma[QUANT_TABLE_SIZE_BYTES] = {
112    17, 18, 24, 47, 99, 99, 99, 99,
113    18, 21, 26, 66, 99, 99, 99, 99,
114    24, 26, 56, 99, 99, 99, 99, 99,
115    47, 66, 99, 99, 99, 99, 99, 99,
116    99, 99, 99, 99, 99, 99, 99, 99,
117    99, 99, 99, 99, 99, 99, 99, 99,
118    99, 99, 99, 99, 99, 99, 99, 99,
119    99, 99, 99, 99, 99, 99, 99, 99
120};
121
122/*****************************************************************************/
123/*  \brief   gZigZag                                                         */
124/*                                                                           */
125/*  Zigzag scan pattern                                                      */
126/*****************************************************************************/
127const IMG_UINT8 gZigZag[] = {
128    0,  1,  8, 16,  9,  2,  3, 10,
129    17, 24, 32, 25, 18, 11,  4,  5,
130    12, 19, 26, 33, 40, 48, 41, 34,
131    27, 20, 13,  6,  7, 14, 21, 28,
132    35, 42, 49, 56, 57, 50, 43, 36,
133    29, 22, 15, 23, 30, 37, 44, 51,
134    58, 59, 52, 45, 38, 31, 39, 46,
135    53, 60, 61, 54, 47, 55, 62, 63
136};
137
138/*****************************************************************************/
139/*  \brief   gMarkerDataLumaDc                                               */
140/*                                                                           */
141/*  Contains the data that needs to be sent in the marker segment of an      */
142/*  interchange format JPEG stream or an abbreviated format table            */
143/*  specification data stream.                                               */
144/*  Specifies the huffman table used for encoding the luminance DC           */
145/*  coefficient differences. The table represents Table K.3 of               */
146/*  IS0/IEC 10918-1:1994(E)                                                  */
147/*****************************************************************************/
148const IMG_UINT8 gMarkerDataLumaDc[] = {
149    //TcTh  Li
150    0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
151    0x00, 0x00, 0x00, 0x00, 0x00,
152    // Vi
153    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
154};
155
156/*****************************************************************************/
157/*  \brief   gMarkerDataLumaAc                                               */
158/*                                                                           */
159/*  Contains the data that needs to be sent in the marker segment of an      */
160/*  interchange format JPEG stream or an abbreviated format table            */
161/*  specification data stream.                                               */
162/*  Specifies the huffman table used for encoding the luminance AC           */
163/*  coefficients. The table represents Table K.5 of IS0/IEC 10918-1:1994(E)  */
164/*****************************************************************************/
165const IMG_UINT8 gMarkerDataLumaAc[] = {
166    // TcTh  Li
167    0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
168    0x04, 0x00, 0x00, 0x01, 0x7D,
169    // Vi
170    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
171    0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
172    0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
173    0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
174    0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
175    0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
176    0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75,
177    0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
178    0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3,
179    0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
180    0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
181    0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
182    0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4,
183    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
184};
185
186/*****************************************************************************/
187/*  \brief   gMarkerDataChromaDc                                             */
188/*                                                                           */
189/*  Contains the data that needs to be sent in the marker segment of an      */
190/*  interchange format JPEG stream or an abbreviated format table            */
191/*  specification data stream.                                               */
192/*  Specifies the huffman table used for encoding the chrominance DC         */
193/*  coefficient differences. The table represents Table K.4 of               */
194/*  IS0/IEC 10918-1:1994(E)                                                  */
195/*****************************************************************************/
196const IMG_UINT8 gMarkerDataChromaDc[] = {
197    // TcTh Li
198    0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
199    0x00, 0x00, 0x00, 0x00, 0x00,
200
201    // Vi
202    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
203};
204
205/*****************************************************************************/
206/*  \brief   gMarkerDataChromaAc                                             */
207/*                                                                           */
208/*  Contains the data that needs to be sent in the marker segment of an      */
209/*  interchange format JPEG stream or an abbreviated format table            */
210/*  specification data stream.                                               */
211/*  Specifies the huffman table used for encoding the chrominance AC         */
212/*  coefficients. The table represents Table K.6 of IS0/IEC 10918-1:1994(E)  */
213/*****************************************************************************/
214const IMG_UINT8 gMarkerDataChromaAc[] = {
215    // TcTh
216    0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
217    0x04, 0x00, 0x01, 0x02, 0x77,
218
219    // Vi
220    0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
221    0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
222    0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1,
223    0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
224    0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
225    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
226    0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
227    0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
228    0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
229    0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
230    0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
231    0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
232    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
233    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
234};
235
236/*****************************************************************************/
237/*  \brief   gLumaDCCode                                                     */
238/*                                                                           */
239/*  Contains the code words to encode the luminance DC coefficient           */
240/*  differences. The code words are mentioned in table K.3 of                */
241/*  ISO/IEC 10918-1:1994(E)                                                  */
242/*****************************************************************************/
243const IMG_UINT16 gLumaDCCode[] = {
244    0x0000, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006,
245    0x000E, 0x001E, 0x003E, 0x007E, 0x00FE, 0x01FE
246};
247
248/*****************************************************************************/
249/*  \brief   gLumaDCSize                                                     */
250/*                                                                           */
251/*  Contains the code length of the code words that are used to encode the   */
252/*  luminance DC coefficient differences. The code lengths are mentioned in  */
253/*  table K.3 of ISO/IEC 10918-1:1994(E)                                     */
254/*****************************************************************************/
255const IMG_UINT8 gLumaDCSize[] = {
256    0x0002, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
257    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009
258};
259
260/*****************************************************************************/
261/*  \brief   gChromaDCCode                                                   */
262/*                                                                           */
263/*  Contains the code words to encode the chrominance DC coefficient         */
264/*  differences. The code words are mentioned in table K.4 of                */
265/*  ISO/IEC 10918-1:1994(E)                                                  */
266/*****************************************************************************/
267const IMG_UINT16 gChromaDCCode[] = {
268    0x0000, 0x0001, 0x0002, 0x0006, 0x000E, 0x001E,
269    0x003E, 0x007E, 0x00FE, 0x01FE, 0x03FE, 0x07FE
270};
271
272/*****************************************************************************/
273/*  \brief   gChromaDCSize                                                   */
274/*                                                                           */
275/*  Contains the code length of the code words that are used to encode the   */
276/*  chrominance DC coefficient differences. The code lengths are mentioned in*/
277/*  table K.4 of ISO/IEC 10918-1:1994(E)                                     */
278/*****************************************************************************/
279const IMG_UINT8 gChromaDCSize[] = {
280    0x0002, 0x0002, 0x0002, 0x0003, 0x0004, 0x0005,
281    0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B
282};
283
284
285/*****************************************************************************/
286/*  \brief   gLumaACCode                                                     */
287/*                                                                           */
288/*  Contains the code words to encode the luminance AC coefficients. The     */
289/*  code words are arrange in the increasing order of run followed by size as*/
290/*  in table K.5 of ISO/IEC 10918-1:1994(E)                                  */
291/*****************************************************************************/
292const IMG_UINT16 gLumaACCode[] = {
293    0x000A, 0x0000, 0x0001, 0x0004, 0x000B, 0x001A, 0x0078, 0x00F8, 0x03F6,
294    0xFF82, 0xFF83, /* codes for run 0 */
295    0x000C, 0x001B, 0x0079, 0x01F6, 0x07F6, 0xFF84, 0xFF85, 0xFF86,
296    0xFF87, 0xFF88, /* codes for run 1 */
297    0x001C, 0x00F9, 0x03F7, 0x0FF4, 0xFF89, 0xFF8A, 0xFF8b, 0xFF8C,
298    0xFF8D, 0xFF8E, /* codes for run 2 */
299    0x003A, 0x01F7, 0x0FF5, 0xFF8F, 0xFF90, 0xFF91, 0xFF92, 0xFF93,
300    0xFF94, 0xFF95, /* codes for run 3 */
301    0x003B, 0x03F8, 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B,
302    0xFF9C, 0xFF9D, /* codes for run 4 */
303    0x007A, 0x07F7, 0xFF9E, 0xFF9F, 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3,
304    0xFFA4, 0xFFA5, /* codes for run 5 */
305    0x007B, 0x0FF6, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB,
306    0xFFAC, 0xFFAD, /* codes for run 6 */
307    0x00FA, 0x0FF7, 0xFFAE, 0xFFAF, 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3,
308    0xFFB4, 0xFFB5, /* codes for run 7 */
309    0x01F8, 0x7FC0, 0xFFB6, 0xFFB7, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB,
310    0xFFBC, 0xFFBD, /* codes for run 8 */
311    0x01F9, 0xFFBE, 0xFFBF, 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4,
312    0xFFC5, 0xFFC6, /* codes for run 9 */
313    0x01FA, 0xFFC7, 0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD,
314    0xFFCE, 0xFFCF, /* codes for run A */
315    0x03F9, 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6,
316    0xFFD7, 0xFFD8, /* codes for run B */
317    0x03FA, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
318    0xFFE0, 0xFFE1, /* codes for run C */
319    0x07F8, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8,
320    0xFFE9, 0xFFEA, /* codes for run D */
321    0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF, 0xFFF0, 0xFFF1, 0xFFF2,
322    0xFFF3, 0xFFF4, /* codes for run E */
323    0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD,
324    0xFFFE, 0x07F9  /* codes for run F */
325};
326
327/*****************************************************************************/
328/*  \brief   gLumaACSize                                                     */
329/*                                                                           */
330/*  Contains the code length of the code words that are used to encode the   */
331/*  luminance AC coefficients. The code lengths as in table K.5 of           */
332/*  ISO/IEC 10918-1:1994(E), are arranged in the increasing order of run     */
333/*  followed by size                                                         */
334/*****************************************************************************/
335const IMG_UINT8 gLumaACSize[] = {
336    0x04, 0x02, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0A, 0x10, 0x10,/* run 0 */
337    0x04, 0x05, 0x07, 0x09, 0x0B, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 1 */
338    0x05, 0x08, 0x0A, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 2 */
339    0x06, 0x09, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 3 */
340    0x06, 0x0A, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 4 */
341    0x07, 0x0B, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 5 */
342    0x07, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 6 */
343    0x08, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 7 */
344    0x09, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 8 */
345    0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 9 */
346    0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run A */
347    0x0A, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run B */
348    0x0A, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run C */
349    0x0B, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run D */
350    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run E */
351    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0B /* run F */
352};
353
354/*****************************************************************************/
355/*  \brief   gChromaACCode                                                   */
356/*                                                                           */
357/*  Contains the code words to encode the chromiannce AC coefficients. The   */
358/*  code words are arrange in the increasing order of run followed by size   */
359/*  as in table K.6 of ISO/IEC 10918-1:1994(E)                               */
360/*****************************************************************************/
361const IMG_UINT16 gChromaACCode[] = {
362    0x0000, 0x0001, 0x0004, 0x000A, 0x0018, 0x0019, 0x0038, 0x0078, 0x01F4,
363    0x03F6, 0x0FF4, /* codes for run 0 */
364    0x000B, 0x0039, 0x00F6, 0x01F5, 0x07F6, 0x0FF5, 0xFF88, 0xFF89,
365    0xFF8A, 0xFF8B, /* codes for run 1 */
366    0x001A, 0x00F7, 0x03F7, 0x0FF6, 0x7FC2, 0xFF8C, 0xFF8D, 0xFF8E,
367    0xFF8F, 0xFF90, /* codes for run 2 */
368    0x001B, 0x00F8, 0x03F8, 0x0FF7, 0xFF91, 0xFF92, 0xFF93, 0xFF94,
369    0xFF95, 0xFF96, /* codes for run 3 */
370    0x003A, 0x01F6, 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C,
371    0xFF9D, 0xFF9E, /* codes for run 4 */
372    0x003B, 0x03F9, 0xFF9F, 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4,
373    0xFFA5, 0xFFA6, /* codes for run 5 */
374    0x0079, 0x07F7, 0xFFA7, 0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC,
375    0xFFAD, 0xFFAE, /* codes for run 6 */
376    0x007A, 0x07F8, 0xFFAF, 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4,
377    0xFFB5, 0xFFB6, /* codes for run 7 */
378    0x00F9, 0xFFB7, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD,
379    0xFFBE, 0xFFBF, /* codes for run 8 */
380    0x01F7, 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6,
381    0xFFC7, 0xFFC8, /* codes for run 9 */
382    0x01F8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
383    0xFFD0, 0xFFD1, /* codes for run A */
384    0x01F9, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7, 0xFFD8,
385    0xFFD9, 0xFFDA, /* codes for run B */
386    0x01FA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF, 0xFFE0, 0xFFE1,
387    0xFFE2, 0xFFE3, /* codes for run C */
388    0x07F9, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8, 0xFFE9, 0xFFEA,
389    0xFFEb, 0xFFEC, /* codes for run D */
390    0x3FE0, 0xFFED, 0xFFEE, 0xFFEF, 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3,
391    0xFFF4, 0xFFF5, /* codes for run E */
392    0x7FC3, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD,
393    0xFFFE, 0x03FA  /* codes for run F */
394};
395
396/*****************************************************************************/
397/*  \brief   gChromaACSize                                                   */
398/*                                                                           */
399/*  Contains the code length of the code words that are used to encode the   */
400/*  chrominance AC coefficients. The code lengths as in table K.5 of         */
401/*  ISO/IEC 10918-1:1994(E), are arranged in the increasing order of run     */
402/*  followed by size                                                         */
403/*****************************************************************************/
404const IMG_UINT8 gChromaACSize[] = {
405    0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x09, 0x0A, 0x0C,/* run 0 */
406    0x04, 0x06, 0x08, 0x09, 0x0B, 0x0C, 0x10, 0x10, 0x10, 0x10,/* run 1 */
407    0x05, 0x08, 0x0A, 0x0C, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 2 */
408    0x05, 0x08, 0x0A, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 3 */
409    0x06, 0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 4 */
410    0x06, 0x0A, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 5 */
411    0x07, 0x0B, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 6 */
412    0x07, 0x0B, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 7 */
413    0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 8 */
414    0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run 9 */
415    0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run A */
416    0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run B */
417    0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run C */
418    0x0B, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run D */
419    0x0E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,/* run E */
420    0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0A /* run F */
421};
422
423/*****************************************************************************/
424/*  \brief   gSize                                                           */
425/*                                                                           */
426/*  Table used in the computation of 4 lease significant bits 'SSSS' as      */
427/*  specified in table F.1 and F.2 of ISO/IEC 10918-1:1994(E). These values  */
428/*  are used to computes the 4 least significant bits and are not exactly    */
429/*  the values mentioned in the table                                        */
430/*****************************************************************************/
431const IMG_UINT8 gSize[] = {
432    0,
433    1,
434    2, 2,
435    3, 3, 3, 3,
436    4, 4, 4, 4, 4, 4, 4, 4,
437    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
438};
439
440int customize_quantization_tables(unsigned char *luma_matrix,
441                                  unsigned char *chroma_matrix,
442                                  unsigned int ui32Quality)
443{
444    unsigned int uc_qVal;
445    unsigned int uc_j;
446
447    if((NULL == luma_matrix) || (NULL == chroma_matrix) ||
448       (ui32Quality < 1) || (ui32Quality > 100))
449        return 1;
450
451    /* Compute luma quantization table */
452    ui32Quality = (ui32Quality<50) ? (5000/ui32Quality) : (200-ui32Quality*2);
453    for(uc_j=0; uc_j<QUANT_TABLE_SIZE_BYTES; ++uc_j) {
454        uc_qVal = (gQuantLuma[uc_j] * ui32Quality + 50) / 100;
455        uc_qVal =  (uc_qVal>0xFF)? 0xFF:uc_qVal;
456        uc_qVal =  (uc_qVal<1)? 1:uc_qVal;
457        luma_matrix[uc_j] = (unsigned char)uc_qVal;
458    }
459
460    /* Compute chroma quantization table */
461    for(uc_j=0; uc_j<QUANT_TABLE_SIZE_BYTES; ++uc_j) {
462        uc_qVal = (gQuantChroma[uc_j] * ui32Quality + 50) / 100;
463        uc_qVal =  (uc_qVal>0xFF)? 0xFF:uc_qVal;
464        uc_qVal =  (uc_qVal<1)? 1:uc_qVal;
465        chroma_matrix[uc_j] = (unsigned char)uc_qVal;
466    }
467
468    return 0;
469}
470
471/*****************************************************************************/
472/*                                                                           */
473/* Function Name : fPutBitsToBuffer                                          */
474/*                                                                           */
475/* Description   : The function write a bit string into the stream           */
476/*                                                                           */
477/* Inputs        :                                                           */
478/* BitStream     : Pointer to the stream context                             */
479/* NoOfBits      : Size of the bit string                                    */
480/* ActualBits    : Bit string to be written                                  */
481/*                                                                           */
482/* Outputs       : On return the function has written the bit string into    */
483/*                 the stream                                                */
484/*                                                                           */
485/* Returns       : void                                                      */
486/*                                                                           */
487/* Revision History:                                                         */
488/*                                                                           */
489/* 14 12 2001 BG Creation                                                    */
490/*                                                                           */
491/*****************************************************************************/
492
493void fPutBitsToBuffer(STREAMTYPEW *BitStream, IMG_UINT8 NoOfBytes, IMG_UINT32 ActualBits)
494{
495    IMG_UINT8 ui8Lp;
496    IMG_UINT8 *pui8S;
497
498    pui8S = (IMG_UINT8 *)BitStream->Buffer;
499    pui8S += BitStream->Offset;
500
501    for (ui8Lp = NoOfBytes; ui8Lp > 0; ui8Lp--)
502        *(pui8S++) = ((IMG_UINT8 *) & ActualBits)[ui8Lp-1];
503
504    BitStream->Offset += NoOfBytes;
505}
506
507
508
509/***********************************************************************************
510 * Function Name      : AllocateCodedDataBuffers
511 * Inputs             :
512 * Outputs            :
513 * Returns            : PVRRC
514 * Description        : Allocates Device memory for coded buffers and build BUFFERINFO array
515 ************************************************************************************/
516
517IMG_ERRORCODE AllocateCodedDataBuffers(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext)
518{
519    IMG_UINT8 ui8Loop;
520
521    for (ui8Loop = 0 ; ui8Loop < pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers; ui8Loop ++)
522        if (pContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo == NULL) {
523            pContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui32DataBufferSizeBytes = ((DATA_BUFFER_SIZE(pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan) + sizeof(BUFFER_HEADER)) + 3) & ~3;
524            pContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui32DataBufferUsedBytes = 0;
525            pContext->sScan_Encode_Info.aBufferTable[ui8Loop].i8MTXNumber = 0; // Indicates buffer is idle
526            pContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui16ScanNumber = 0; // Indicates buffer is idle
527            pContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo =
528                (unsigned char *)pContext->jpeg_coded_buf.pMemInfo + PNW_JPEG_HEADER_MAX_SIZE + ui8Loop * pContext->ui32SizePerCodedBuffer;
529
530        }
531
532    return IMG_ERR_OK;
533}
534
535
536#if 0
537/***********************************************************************************
538 * Function Name      : FreeCodedDataBuffers
539 * Inputs             :
540 * Outputs            :
541 * Returns            : PVRRC
542 * Description        : Loops through our coded data buffers and frees them
543 ************************************************************************************/
544
545IMG_UINT32 FreeCodedDataBuffers(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext)
546{
547    IMG_UINT8 ui8Loop;
548    ui8Loop = pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers;
549    /* Spin through and remove */
550    while (ui8Loop--)
551        if (pContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo != NULL) {
552            /*      MMFreeDeviceMemory( &(pContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo));*/
553            pContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo = NULL;
554        }
555
556    return 0;
557}
558#endif
559
560
561
562void SetupMCUDetails(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext,
563                     const IMG_UINT32 uiComponentNumber ,
564                     const IMG_UINT32 uiWidthBlocks ,
565                     const IMG_UINT32 uiHeightBlocks,
566                     const IMG_UINT32 uiLastRow,
567                     const IMG_UINT32 uiLastCol)
568{
569    MCUCOMPONENT* pMCUComp;
570
571    if (uiComponentNumber >=  MTX_MAX_COMPONENTS)
572        return;
573
574    pMCUComp = &pContext->pMTXSetup->MCUComponent[uiComponentNumber];
575
576    pMCUComp->ui32WidthBlocks = uiWidthBlocks * 8;
577    pMCUComp->ui32HeightBlocks = uiHeightBlocks * 8;
578
579    pMCUComp->ui32XLimit = uiLastCol;
580    pMCUComp->ui32YLimit = uiLastRow;
581
582    drv_debug_msg(VIDEO_DEBUG_GENERAL, "MCU Details %i : %ix%i  %i  %i\n", uiComponentNumber, uiWidthBlocks , uiHeightBlocks ,  uiLastCol , uiLastRow);
583
584}
585
586
587/*****************************************************************************/
588/*                                                                           */
589/* Function Name : InitializeJpegEncode                                      */
590/*                                                                           */
591/* Description   : The function initializes an instance of the JPEG encoder  */
592/* Inputs/Outputs: Pointer to the JPEG Host context                                                      */
593/*                 Pointer to a IMG_FRAME type which will be created to be filled        */
594/*                      with the source image data                                                                               */
595/*****************************************************************************/
596
597IMG_ERRORCODE InitializeJpegEncode(TOPAZSC_JPEG_ENCODER_CONTEXT * pContext, object_surface_p __maybe_unused pTFrame)
598{
599    IMG_ERRORCODE rc = IMG_ERR_OK;
600    IMG_UINT8  uc_i = 0;
601    IMG_UINT16 ui16_height_min;
602    IMG_UINT16 ui16_height_max;
603    IMG_UINT16 ui16_width_min;
604    IMG_UINT16 ui16_width_max;
605    //IMG_UINT16 ui16_width;
606    //IMG_UINT16 ui16_height;
607    IMG_UINT32 uiBlockCount = 0;
608    IMG_UINT16 ui16_comp_width, ui16_comp_height;
609    IMG_UINT8  uc_h_scale_max = 0, uc_v_scale_max = 0, uc_h_scale = 0;
610    IMG_UINT8  uc_v_scale;
611    IMG_UINT16 ui16_height, ui16_width;
612    context_ENC_p ctx = (context_ENC_p)pContext->ctx;
613
614    /*************************************************************************/
615    /* Determine the horizontal and the vertical scaling factor of each of   */
616    /* the components of the image                                           */
617    /*************************************************************************/
618
619    /*FIXME: ONLY support NV12, YV12 here*/
620    /*pTFrame->height isn't the real height of image, since vaCreateSurface
621     * makes it aligned with 32*/
622    ui16_height = pContext->ui32OutputHeight;
623    ui16_width = pContext->ui32OutputWidth;
624
625    switch (pContext->eFormat) {
626    case IMG_CODEC_YV16: /*422 format*/
627        ui16_height_min = ui16_height;
628        ui16_height_max = ui16_height;
629        ui16_width_min = ui16_width >> 1;
630        ui16_width_max = ui16_width;
631        break;
632    case IMG_CODEC_NV12:
633    case IMG_CODEC_IYUV:
634    default:
635        ui16_height_min = ui16_height >> 1;
636        ui16_height_max = ui16_height;
637        ui16_width_min = ui16_width >> 1;
638        ui16_width_max = ui16_width;
639        break;
640    }
641    /*ui16_height_min = ui16_width_min  = 65535;
642    ui16_height_max = ui16_width_max  = 0;
643
644    for(uc_i = 0; uc_i < pContext->pMTXSetup->ui32ComponentsInScan; uc_i++)
645    {
646    ui16_width  = pTFrame->Width;
647    if(ui16_width_min > ui16_width)
648    ui16_width_min  = ui16_width;
649    if(ui16_width_max < ui16_width)
650    ui16_width_max  = ui16_width;
651
652    ui16_height = pTFrame->Height;
653    if(ui16_height_min > ui16_height)
654    ui16_height_min = ui16_height;
655    if(ui16_height_max < ui16_height)
656    ui16_height_max = ui16_height;
657    }
658    */
659    /*********************************************************************/
660    /* Determine the horizonal and the vertical sampling frequency of    */
661    /* each of components in the image                                   */
662    /*********************************************************************/
663
664    uc_h_scale_max = (ui16_width_max + ui16_width_min - 1) /
665                     ui16_width_min;
666    uc_v_scale_max = (ui16_height_max + ui16_height_min - 1) /
667                     ui16_height_min;
668
669    for (uc_i = 0; uc_i < pContext->pMTXSetup->ui32ComponentsInScan; uc_i++) {
670
671        /*      ui16_comp_width  = pTFrame->aui32ComponentInfo[uc_i].ui32Width;
672                ui16_comp_height = pTFrame->aui32ComponentInfo[uc_i].ui32Height;*/
673        /*Support NV12, YV12, YV16 here. uc_h/v_scale should be
674         * 2x2(Y) or 1x1(U/V)*/
675        if (0 == uc_i) {
676            ui16_comp_width  = ui16_width;
677            ui16_comp_height = ui16_height;
678        } else {
679            switch (pContext->eFormat) {
680            case IMG_CODEC_YV16: /*422 format*/
681                ui16_comp_width  = ui16_width >> 1;
682                ui16_comp_height = ui16_height;
683                break;
684            case IMG_CODEC_NV12:
685            case IMG_CODEC_IYUV:
686            default:
687                ui16_comp_width  = ui16_width >> 1;
688                ui16_comp_height = ui16_height >> 1;
689            }
690        }
691
692        uc_h_scale       = (ui16_comp_width *  uc_h_scale_max) /
693                           ui16_width_max;
694        uc_v_scale       = (ui16_comp_height * uc_v_scale_max) /
695                           ui16_height_max;
696
697        uiBlockCount += (uc_h_scale * uc_v_scale);
698
699        switch (ISCHROMAINTERLEAVED(pContext->eFormat)) {
700        case C_INTERLEAVE:
701            // Chroma format is byte interleaved, as the engine runs using planar colour surfaces we need
702            // to fool the engine into offsetting by 16 instead of 8
703            if (uc_i > 0) { // if chroma, then double values
704                uc_h_scale <<= 1;
705                ui16_comp_width <<= 1;
706            }
707            break;
708        case LC_UVINTERLEAVE:
709            //Y0UY1V_8888 or Y0VY1U_8888 format
710            ui16_comp_width <<= 1;
711            break;
712        case LC_VUINTERLEAVE:
713            //Y0UY1V_8888 or Y0VY1U_8888 format
714            ui16_comp_width <<= 1;
715            break;
716        default:
717            break;
718        }
719
720        SetupMCUDetails(pContext, uc_i , uc_h_scale, uc_v_scale, ui16_comp_height, ui16_comp_width);
721
722        if (uiBlockCount > BLOCKCOUNTMAXPERCOLOURPLANE) {
723            return IMG_ERR_INVALID_SIZE;
724        }
725
726    }
727
728    return rc;
729}
730
731
732/***********************************************************************************
733  Function Name      : JPGEncodeBegin
734Inputs             : hInstance,psJpegInfo,ui32Quality
735Outputs            :
736Returns            : PVRRC
737Description        : Marks the begining of a JPEG encode and sets up encoder
738 ************************************************************************************/
739
740/*IMG_ERRORCODE JPGEncodeBegin(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext, IMG_FRAME *pTFrame)
741{
742    IMG_UINT32 ReturnCode = 0;
743    ReturnCode = InitializeJpegEncode(pContext, pTFrame);
744
745    return ReturnCode;
746} */
747
748#if 0
749/*****************************************************************************/
750/*                                                                           */
751/* Function Name : EncodeMarkerSegment                                       */
752/*                                                                           */
753/* Description   : Writes the marker segment of a JPEG stream according to   */
754/*                 the syntax mentioned in section B.2.4 of                  */
755/*                 ISO/IEC 10918-1:1994E                                     */
756/*                                                                           */
757/* Inputs        : Pointer to the JPEG Context and coded output buffer       */
758/*                                                                           */
759/* Processing    : Writes each of the following into the marker segment of   */
760/*                 the JPEG stream                                           */
761/*                 - luminance and chrominance quantization tables           */
762/*                 - huffman tables used for encoding the luminance and      */
763/*                   chrominance AC coefficients                             */
764/*                 - huffman tables used for encoding the luminance and      */
765/*                   chorimance  DC coefficient differences                  */
766/*                                                                           */
767/*                                                                           */
768/*****************************************************************************/
769IMG_UINT32 Legacy_EncodeMarkerSegment(LEGACY_JPEG_ENCODER_CONTEXT *pContext,
770                                      IMG_UINT8 *puc_stream_buff)
771{
772    STREAMTYPEW s_streamW;
773    IMG_UINT8 uc_i;
774
775    s_streamW.Offset = 0;
776    s_streamW.Buffer = puc_stream_buff;
777
778    /* Writing the start of image marker */
779    fPutBitsToBuffer(&s_streamW, 2, START_OF_IMAGE);
780
781    /* Writing the quantization table for luminance into the stream */
782    fPutBitsToBuffer(&s_streamW, 2, DQT_MARKER);
783
784    fPutBitsToBuffer(&s_streamW, 3, LQPQ << 4); // 20 bits = LQPQ, 4 bits = 0 (Destination identifier for the luminance quantizer tables)
785
786    for (uc_i = 0; uc_i < PELS_IN_BLOCK; uc_i++) {
787        fPutBitsToBuffer(&s_streamW, 1, pContext->pvLowLevelEncContext->Qmatrix[0][gZigZag[uc_i]]);
788    }
789
790    /* Writing the quantization table for chrominance into the stream */
791    fPutBitsToBuffer(&s_streamW, 2, DQT_MARKER);
792
793    fPutBitsToBuffer(&s_streamW, 3, (LQPQ << 4) | 1); // 20 bits = LQPQ, 4 bits = 1 (Destination identifier for the chrominance quantizer tables)
794
795    for (uc_i = 0; uc_i < PELS_IN_BLOCK; uc_i++) {
796        fPutBitsToBuffer(&s_streamW, 1, pContext->pvLowLevelEncContext->Qmatrix[1][gZigZag[uc_i]]);
797    }
798
799    /* Writing the huffman tables for luminance dc coeffs */
800    /* Write the DHT Marker */
801    fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
802    fPutBitsToBuffer(&s_streamW, 2, LH_DC);
803    for (uc_i = 0; uc_i < LH_DC - 2; uc_i++) {
804        fPutBitsToBuffer(&s_streamW, 1, gMarkerDataLumaDc[uc_i]);
805    }
806    /* Writing the huffman tables for luminance ac coeffs */
807    /* Write the DHT Marker */
808    fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
809    fPutBitsToBuffer(&s_streamW, 2, LH_AC);
810    for (uc_i = 0; uc_i < LH_AC - 2; uc_i++) {
811        fPutBitsToBuffer(&s_streamW, 1, gMarkerDataLumaAc[uc_i]);
812    }
813    /* Writing the huffman tables for chrominance dc coeffs */
814    fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
815    fPutBitsToBuffer(&s_streamW, 2, LH_DC);
816    for (uc_i = 0; uc_i < LH_DC - 2; uc_i++) {
817        fPutBitsToBuffer(&s_streamW, 1, gMarkerDataChromaDc[uc_i]);
818    }
819    /* Writing the huffman tables for luminance ac coeffs */
820    /* Write the DHT Marker */
821    fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
822    fPutBitsToBuffer(&s_streamW, 2, LH_AC);
823    for (uc_i = 0; uc_i < LH_AC - 2; uc_i++) {
824        fPutBitsToBuffer(&s_streamW, 1, gMarkerDataChromaAc[uc_i]);
825    }
826
827
828    return s_streamW.Offset;
829}
830#endif
831
832/*****************************************************************************/
833/*                                                                           */
834/* Function Name : EncodeMarkerSegment                                       */
835/*                                                                           */
836/* Description   : Writes the marker segment of a JPEG stream according to   */
837/*                 the syntax mentioned in section B.2.4 of                  */
838/*                 ISO/IEC 10918-1:1994E                                     */
839/*                                                                           */
840/* Inputs        : Pointer to the JPEG Context and coded output buffer       */
841/*                                                                           */
842/* Processing    : Writes each of the following into the marker segment of   */
843/*                 the JPEG stream                                           */
844/*                 - luminance and chrominance quantization tables           */
845/*                 - huffman tables used for encoding the luminance and      */
846/*                   chrominance AC coefficients                             */
847/*                 - huffman tables used for encoding the luminance and      */
848/*                   chorimance  DC coefficient differences                  */
849/*                                                                           */
850/*****************************************************************************/
851
852IMG_UINT32 EncodeMarkerSegment(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext,
853                               IMG_UINT8 *puc_stream_buff, IMG_BOOL bIncludeHuffmanTables)
854{
855    STREAMTYPEW s_streamW;
856    IMG_UINT8 uc_i;
857
858    s_streamW.Offset = 0;
859    s_streamW.Buffer = puc_stream_buff;
860
861    /* Writing the start of image marker */
862    fPutBitsToBuffer(&s_streamW, 2, START_OF_IMAGE);
863
864    /* Writing the quantization table for luminance into the stream */
865    fPutBitsToBuffer(&s_streamW, 2, DQT_MARKER);
866
867    fPutBitsToBuffer(&s_streamW, 3, LQPQ << 4); // 20 bits = LQPQ, 4 bits = 0 (Destination identifier for the luminance quantizer tables)
868
869    IMG_ASSERT(PELS_IN_BLOCK <= QUANT_TABLE_SIZE_BYTES);
870    for (uc_i = 0; uc_i < PELS_IN_BLOCK; uc_i++) {
871        // Write zigzag ordered luma quantization values to our JPEG header
872        fPutBitsToBuffer(&s_streamW, 1, pContext->psTablesBlock->aui8LumaQuantParams[gZigZag[uc_i]]);
873    }
874
875    /* Writing the quantization table for chrominance into the stream */
876    fPutBitsToBuffer(&s_streamW, 2, DQT_MARKER);
877
878    fPutBitsToBuffer(&s_streamW, 3, (LQPQ << 4) | 1); // 20 bits = LQPQ, 4 bits = 1 (Destination identifier for the chrominance quantizer tables)
879
880    for (uc_i = 0; uc_i < PELS_IN_BLOCK; uc_i++) {
881        // Write zigzag ordered chroma quantization values to our JPEG header
882        fPutBitsToBuffer(&s_streamW, 1, pContext->psTablesBlock->aui8ChromaQuantParams[gZigZag[uc_i]]);
883    }
884
885    if (bIncludeHuffmanTables) {
886        /* Writing the huffman tables for luminance dc coeffs */
887        /* Write the DHT Marker */
888        fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
889        fPutBitsToBuffer(&s_streamW, 2, LH_DC);
890        for (uc_i = 0; uc_i < LH_DC - 2; uc_i++) {
891            fPutBitsToBuffer(&s_streamW, 1, gMarkerDataLumaDc[uc_i]);
892        }
893        /* Writing the huffman tables for luminance ac coeffs */
894        /* Write the DHT Marker */
895        fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
896        fPutBitsToBuffer(&s_streamW, 2, LH_AC);
897        for (uc_i = 0; uc_i < LH_AC - 2; uc_i++) {
898            fPutBitsToBuffer(&s_streamW, 1, gMarkerDataLumaAc[uc_i]);
899        }
900        /* Writing the huffman tables for chrominance dc coeffs */
901        fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
902        fPutBitsToBuffer(&s_streamW, 2, LH_DC);
903        for (uc_i = 0; uc_i < LH_DC - 2; uc_i++) {
904            fPutBitsToBuffer(&s_streamW, 1, gMarkerDataChromaDc[uc_i]);
905        }
906        /* Writing the huffman tables for luminance ac coeffs */
907        /* Write the DHT Marker */
908        fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
909        fPutBitsToBuffer(&s_streamW, 2, LH_AC);
910        for (uc_i = 0; uc_i < LH_AC - 2; uc_i++) {
911            fPutBitsToBuffer(&s_streamW, 1, gMarkerDataChromaAc[uc_i]);
912        }
913    }
914
915    // Activate Restart markers
916    if (pContext->sScan_Encode_Info.ui16CScan > 1) {
917        // Only use restart intervals if we need them (ie. multiple Scan encode and/or parallel CB encode)
918        fPutBitsToBuffer(&s_streamW, 2, 0xFFDD); //Marker header
919        fPutBitsToBuffer(&s_streamW, 2, 4); // Byte size of marker (header not included)
920        fPutBitsToBuffer(&s_streamW, 2, pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan); // Restart Interval (same as MCUs per buffer)
921    }
922
923    return s_streamW.Offset;
924}
925
926#if 0
927/***********************************************************************************
928  Function Name      : JPGEncodeMarker
929Inputs             :    Pointer to JPEG Encoder context
930Pointer to coded buffer stream
931Pointer to pui32BytesWritten value
932Outputs            : ui8BitStreamBuffer,pui32BytesWritten
933Description        : Writes a JPEG marker segment to the bit stream
934 ************************************************************************************/
935
936IMG_UINT32 Legacy_JPGEncodeMarker(/*in */               LEGACY_JPEG_ENCODER_CONTEXT *pContext ,
937        /*in */         IMG_UINT8* pui8BitStreamBuffer ,
938        /*out*/         IMG_UINT32 *pui32BytesWritten)
939{
940#ifdef JPEG_VERBOSE
941    printf("PVRJPGEncodeMarker");
942#endif
943
944    if (pContext->eCurrentActive != LEGACY_JPEG_API_CURRENT_ACTIVE_ENCODE) {
945        /* Cannot be called outside begin and end*/
946        return 2;
947    }
948
949    *pui32BytesWritten += Legacy_EncodeMarkerSegment(pContext, pui8BitStreamBuffer);
950
951    return 0;
952}
953#endif
954
955/***********************************************************************************
956  Function Name      : JPGEncodeMarker
957Inputs             :    Pointer to JPEG Encoder context
958Pointer to coded buffer stream
959Pointer to Byteswritten value
960bIncludeHuffmanTables - Set to true to include the huffman tables in the stream
961Outputs            : ui8BitStreamBuffer,pui32BytesWritten
962Description        : Writes a JPEG marker segment to the bit stream
963 ************************************************************************************/
964
965IMG_UINT32 JPGEncodeMarker(/*in */              TOPAZSC_JPEG_ENCODER_CONTEXT *pContext ,
966        /*in */         IMG_UINT8* pui8BitStreamBuffer ,
967        /*out*/         IMG_UINT32 *pui32BytesWritten, IMG_BOOL bIncludeHuffmanTables)
968{
969#ifdef JPEG_VERBOSE
970    printf("PVRJPGEncodeMarker");
971#endif
972
973
974    *pui32BytesWritten += EncodeMarkerSegment(pContext, pui8BitStreamBuffer + *pui32BytesWritten, bIncludeHuffmanTables);
975
976    return 0;
977}
978
979#if 0
980/*****************************************************************************/
981/*                                                                           */
982/* Function Name : EncodeFrameHeader                                         */
983/*                                                                           */
984/* Description   : Writes the frame header of a JPEG stream according to     */
985/*                 the syntax mentioned in section B.2.2 of                  */
986/*                 ISO/IEC 10918-1:1994E .                                   */
987/*                                                                           */
988/* Inputs        :                                                           */
989/* ps_jpeg_params: Ptr to the JPEG encoder parameter context                 */
990/* ps_jpeg_comp  : Ptr to the JPEG image component context                   */
991/* puc_stream_buff:Ptr to the bistream buffer from where to start writing    */
992/*                                                                           */
993/* Processing    : Writes each of the following into the frame header of     */
994/*                 the JPEG stream                                           */
995/*                 - JPEG image component identifier                         */
996/*                 - Horizontal and vertical sampling factor                 */
997/*                 - Quantization table identifier for each of the components*/
998/*                                                                           */
999/* Returns       : Number of bytes written into the stream                   */
1000/*                                                                           */
1001/*****************************************************************************/
1002
1003IMG_UINT32 Legacy_EncodeFrameHeader(LEGACY_JPEGENC_ITTIAM_PARAMS *ps_jpeg_params,
1004                                    LEGACY_JPEGENC_ITTIAM_COMPONENT *ps_jpeg_comp,
1005                                    IMG_UINT8 *puc_stream_buff)
1006{
1007    STREAMTYPEW ps_streamW;
1008    IMG_UINT16 ui16_i;
1009    IMG_UINT8  uc_num_comp_in_img;
1010
1011    uc_num_comp_in_img = ps_jpeg_comp->uc_num_comp_in_img;
1012
1013    ps_streamW.Offset = 0;
1014    ps_streamW.Buffer = puc_stream_buff;
1015
1016
1017    if (ps_jpeg_params->uc_isAbbreviated != 0)
1018        fPutBitsToBuffer(&ps_streamW, 2, START_OF_IMAGE);
1019
1020    /* Writing the frame header */
1021    fPutBitsToBuffer(&ps_streamW, 2, SOF_BASELINE_DCT);
1022    /* Frame header length */
1023    fPutBitsToBuffer(&ps_streamW, 2, 8 + 3 * uc_num_comp_in_img);
1024    /* Precision */
1025    fPutBitsToBuffer(&ps_streamW, 1, 8);
1026    /* Height : sample lines */
1027    fPutBitsToBuffer(&ps_streamW, 2, ps_jpeg_params->ui16_height);
1028    /* Width : samples per line */
1029    fPutBitsToBuffer(&ps_streamW, 2, ps_jpeg_params->ui16_width);
1030    /* Number of image components */
1031    fPutBitsToBuffer(&ps_streamW, 1, uc_num_comp_in_img);
1032
1033    if (uc_num_comp_in_img > MAX_COMP_IN_SCAN)
1034        uc_num_comp_in_img = MAX_COMP_IN_SCAN;
1035    for (ui16_i = 0; ui16_i < uc_num_comp_in_img; ui16_i++) {
1036        /* Component identifier */
1037        fPutBitsToBuffer(&ps_streamW, 1, ps_jpeg_comp->puc_comp_id[ui16_i]);
1038
1039        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1040        fPutBitsToBuffer(&ps_streamW, 1, (ps_jpeg_comp->puc_horiz_scale[ui16_i] << 4) | ps_jpeg_comp->puc_vert_scale[ui16_i]);
1041
1042        /* Quantization table destination selector */
1043        fPutBitsToBuffer(&ps_streamW, 1, ps_jpeg_comp->puc_q_table_id[ui16_i]);
1044
1045        ps_jpeg_comp->CompIdtoIndex[ ps_jpeg_comp->puc_comp_id[ui16_i] ] = (IMG_UINT8) ui16_i;
1046    }
1047
1048    //Use if you want start of scan (image data) to align to 32
1049    //fPutBitsToBuffer(&ps_streamW, 1, 0xFF);
1050
1051    return ps_streamW.Offset;
1052}
1053#endif
1054
1055/*****************************************************************************/
1056/*                                                                           */
1057/* Function Name : EncodeFrameHeader                                         */
1058/*                                                                           */
1059/* Description   : Writes the frame header of a JPEG stream according to     */
1060/*                 the syntax mentioned in section B.2.2 of                  */
1061/*                 ISO/IEC 10918-1:1994E .                                   */
1062/*                                                                           */
1063/* Inputs        :                                                           */
1064/*                                      pContext                        - Ptr to the JPEG encoder context        */
1065/*                                      puc_stream_buff         - Ptr to the bistream buffer from        */
1066/*                                                                                      where to start writing                   */
1067/*                                                                           */
1068/* Processing    : Writes each of the following into the frame header of     */
1069/*                 the JPEG stream                                           */
1070/*                 - JPEG image component identifier                         */
1071/*                 - Horizontal and vertical sampling factor                 */
1072/*                 - Quantization table identifier for each of the components*/
1073/*                                                                           */
1074/* Returns       : Number of bytes written into the stream                   */
1075/*                                                                           */
1076/*****************************************************************************/
1077
1078IMG_UINT32 EncodeFrameHeader(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext,
1079                             IMG_UINT8 *puc_stream_buff)
1080{
1081    STREAMTYPEW ps_streamW;
1082    IMG_UINT8  uc_num_comp_in_img;
1083
1084    uc_num_comp_in_img = pContext->pMTXSetup->ui32ComponentsInScan;
1085
1086    ps_streamW.Offset = 0;
1087    ps_streamW.Buffer = puc_stream_buff;
1088
1089
1090    //if(ps_jpeg_params->uc_isAbbreviated != 0)
1091    //   fPutBitsToBuffer(&ps_streamW, 2, START_OF_IMAGE);
1092
1093    /* Writing the frame header */
1094    fPutBitsToBuffer(&ps_streamW, 2, SOF_BASELINE_DCT);
1095    /* Frame header length */
1096    fPutBitsToBuffer(&ps_streamW, 2, 8 + 3 * uc_num_comp_in_img);
1097    /* Precision */
1098    fPutBitsToBuffer(&ps_streamW, 1, 8);
1099    /* Height : sample lines */
1100    fPutBitsToBuffer(&ps_streamW, 2, pContext->ui32OutputHeight);
1101    /* Width : samples per line */
1102    fPutBitsToBuffer(&ps_streamW, 2, pContext->ui32OutputWidth);
1103    /* Number of image components */
1104    fPutBitsToBuffer(&ps_streamW, 1, uc_num_comp_in_img);
1105
1106    //Luma Details
1107    /* Component identifier */
1108    fPutBitsToBuffer(&ps_streamW, 1, 1); //CompId 0 = 1, 1 = 2, 2 = 3
1109    fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks >> 3) << 4) | (pContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks >> 3));
1110    fPutBitsToBuffer(&ps_streamW, 1, 0); // 0 = Luma(0), 1,2 = Chroma(1)
1111
1112    //Chroma Details
1113    if (pContext->pMTXSetup->ui32DataInterleaveStatus < C_INTERLEAVE) { //Chroma planar
1114        fPutBitsToBuffer(&ps_streamW, 1, 2); //CompId 0 = 1, 1 = 2, 2 = 3
1115        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1116        fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[1].ui32WidthBlocks >> 3) << 4) | (pContext->pMTXSetup->MCUComponent[1].ui32HeightBlocks >> 3));
1117        fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
1118        fPutBitsToBuffer(&ps_streamW, 1, 3); //CompId 0 = 1, 1 = 2, 2 = 3
1119        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1120        fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[2].ui32WidthBlocks >> 3) << 4) | (pContext->pMTXSetup->MCUComponent[2].ui32HeightBlocks >> 3));
1121        fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
1122    } else if (pContext->pMTXSetup->ui32DataInterleaveStatus == C_INTERLEAVE) { // Chroma Interleaved
1123        fPutBitsToBuffer(&ps_streamW, 1, 2); //CompId 0 = 1, 1 = 2, 2 = 3
1124        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1125        fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[1].ui32WidthBlocks >> 3) << 3) | (pContext->pMTXSetup->MCUComponent[1].ui32HeightBlocks >> 3));
1126        fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
1127        fPutBitsToBuffer(&ps_streamW, 1, 3); //CompId 0 = 1, 1 = 2, 2 = 3
1128        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1129        fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[2].ui32WidthBlocks >> 3) << 3) | (pContext->pMTXSetup->MCUComponent[2].ui32HeightBlocks >> 3));
1130        fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
1131    } else { //Chroma YUYV - Special case
1132        fPutBitsToBuffer(&ps_streamW, 1, 2); //CompId 0 = 1, 1 = 2, 2 = 3
1133        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1134        fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[1].ui32WidthBlocks >> 3) << 4) | (pContext->pMTXSetup->MCUComponent[1].ui32HeightBlocks >> 3));
1135        fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
1136        fPutBitsToBuffer(&ps_streamW, 1, 3); //CompId 0 = 1, 1 = 2, 2 = 3
1137        /* 4 bit Horizontal and 4 bit vertical sampling factors */
1138        fPutBitsToBuffer(&ps_streamW, 1, ((pContext->pMTXSetup->MCUComponent[2].ui32WidthBlocks >> 3) << 4) | (pContext->pMTXSetup->MCUComponent[2].ui32HeightBlocks >> 3));
1139        fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
1140    }
1141
1142
1143    //Use if you want start of scan (image data) to align to 32
1144    //fPutBitsToBuffer(&ps_streamW, 1, 0xFF);
1145
1146    return ps_streamW.Offset;
1147}
1148
1149#if 0
1150/***********************************************************************************
1151  Function Name      : JPGEncodeHeader
1152Inputs             : Pointer to JPEG Context
1153Outputs            : ui8BitStreamBuffer,pui32BytesWritten
1154Returns            : PVRRC
1155Description        : Writes a frame header to the bit stream
1156Max written 21 bytes
1157 ************************************************************************************/
1158
1159IMG_UINT32 Legacy_JPGEncodeHeader(/*in */               LEGACY_JPEG_ENCODER_CONTEXT *pContext,
1160        /*out */        IMG_UINT8*              pui8BitStreamBuffer ,
1161        /*out*/         IMG_UINT32*             pui32BytesWritten)
1162{
1163#ifdef JPEG_VERBOSE
1164    printf("PVRJPGEncodeHeader");
1165#endif
1166
1167    if (pContext->eCurrentActive != LEGACY_JPEG_API_CURRENT_ACTIVE_ENCODE) {
1168        /* Cannot be called outside begin and end*/
1169        return 2;
1170    }
1171
1172    *pui32BytesWritten += Legacy_EncodeFrameHeader(&pContext->JPEGEncoderParams,
1173                          &pContext->sJPEGEncoderComp,
1174                          pui8BitStreamBuffer + *pui32BytesWritten);
1175    return 0;
1176}
1177#endif
1178
1179/***********************************************************************************
1180  Function Name      : JPGEncodeHeader
1181Inputs             : Pointer to JPEG context
1182Outputs            : ui8BitStreamBuffer,pui32BytesWritten
1183Description        : Writes a frame header to the bit stream
1184Max written 21 bytes
1185 ************************************************************************************/
1186
1187IMG_UINT32 JPGEncodeHeader(/*in */              TOPAZSC_JPEG_ENCODER_CONTEXT *pContext,
1188        /*out */        IMG_UINT8*              pui8BitStreamBuffer ,
1189        /*out*/         IMG_UINT32*             pui32BytesWritten)
1190{
1191#ifdef JPEG_VERBOSE
1192    printf("JPGEncodeHeader");
1193#endif
1194
1195    *pui32BytesWritten += EncodeFrameHeader(pContext, pui8BitStreamBuffer + *pui32BytesWritten);
1196
1197    return 0;
1198}
1199
1200
1201/***********************************************************************************
1202 * Function Name      : SetupIssueSetup
1203 * Inputs             :
1204 pContext - Pointer to JPEG context
1205 ui32ComponentsInScan - Number of components to be encoded in a scan
1206 aui8Planes - Array of 3 bytes indexing YUV colour planes
1207 pTFrame - Pointer to source data
1208 ui32TableA, ui32TableB - Quantization table index values
1209 * Outputs            :
1210 * Returns            : PVRRC
1211 * Description        : Issues the Setup structure to MTX
1212 ************************************************************************************/
1213
1214IMG_UINT32 SetupIssueSetup(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext, const IMG_UINT32 ui32ComponentsInScan, IMG_UINT8 __maybe_unused * aui8Planes,  object_surface_p pTFrame, const IMG_UINT32 ui32TableA , const IMG_UINT32 __maybe_unused ui32TableB)
1215{
1216    IMG_UINT32 ReturnCode = 0;
1217    IMG_INT32 i32Lp;
1218    //COMPONENTPLANE* pSrcPlane;
1219    IMG_UINT32 srf_buf_offset;
1220    context_ENC_p ctx = (context_ENC_p)pContext->ctx;
1221    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
1222    /*TOPAZSC_JPEG_ENCODER_CONTEXT *pContext = pEncContext->psJpegHC;*/
1223
1224#ifdef JPEG_VERBOSE
1225    printf("\nSetupIssueSetup");
1226#endif
1227
1228    pContext->pMTXSetup->ui32ComponentsInScan = ui32ComponentsInScan;
1229    pContext->pMTXSetup->ui32DataInterleaveStatus = ISCHROMAINTERLEAVED(pContext->eFormat);
1230    pContext->pMTXSetup->ui32TableA = ui32TableA;
1231
1232    /*MMUpdateDeviceMemory( pContext->pMemInfoMTXSetup )*/;
1233    // we want to process the handles that have been placed into the buffer
1234    /*for(n=0;n<pContext->pMTXSetup->ui32ComponentsInScan;n++)
1235    {
1236    pSrcPlane = &pContext->pMTXSetup->ComponentPlane[n];
1237    TIMER_START(hardwareduration,"");
1238    MMDeviceMemWriteDeviceMemRef(pContext->pMemInfoMTXSetup->iu32MemoryRegionID, pContext->pMemInfoMTXSetup->hShadowMem, (IMG_UINT32)   ((IMG_BYTE*)&pSrcPlane->ui32PhysAddr - (IMG_BYTE*)pContext->pMTXSetup),TAL_NULL_MANGLER_ID,(IMG_HANDLE) pTFrame->psBuffer->pMemInfo->hShadowMem, pTFrame->aui32ComponentOffset[aui8Planes[n]]);
1239    TIMER_END("HW - MMDeviceMemWriteDeviceMemRef in SetupIssueSetup (hostjpeg.c)");
1240    }*/
1241    /*Support PL12/NV12, YV12/IYUV, YV16*/
1242    srf_buf_offset = pTFrame->psb_surface->buf.buffer_ofs;
1243    RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[0].ui32PhysAddr, srf_buf_offset , &pTFrame->psb_surface->buf);
1244    switch (pContext->eFormat) {
1245    case IMG_CODEC_IYUV:
1246    case IMG_CODEC_PL8:
1247        RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[1].ui32PhysAddr,
1248                             srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height,
1249                             &pTFrame->psb_surface->buf);
1250        RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[2].ui32PhysAddr,
1251                             srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height
1252                             + (pTFrame->psb_surface->stride / 2) *(pTFrame->height / 2),
1253                             &pTFrame->psb_surface->buf);
1254        break;
1255    case IMG_CODEC_IMC2:
1256    case IMG_CODEC_PL12:
1257    case IMG_CODEC_NV12:
1258        RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[1].ui32PhysAddr,
1259                             srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height,
1260                             &pTFrame->psb_surface->buf);
1261        //Byte interleaved surface, so need to force chroma to use single surface by fooling it into
1262        //thinking it's dealing with standard 8x8 planaerblocks
1263        RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[2].ui32PhysAddr,
1264                             srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height
1265                             + 8,
1266                             &pTFrame->psb_surface->buf);
1267        break;
1268    case IMG_CODEC_YV16:
1269        /*V*/
1270        RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[2].ui32PhysAddr,
1271                             srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height,
1272                             &pTFrame->psb_surface->buf);
1273        /*U*/
1274        RELOC_PIC_PARAMS_PNW(&pContext->pMTXSetup->ComponentPlane[1].ui32PhysAddr,
1275                             srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height
1276                             + (pTFrame->psb_surface->stride) *(pTFrame->height) / 2,
1277                             &pTFrame->psb_surface->buf);
1278        break;
1279    default:
1280        drv_debug_msg(VIDEO_DEBUG_ERROR, " Not supported FOURCC %x!\n", pContext->eFormat);
1281        return -1;
1282
1283    }
1284
1285
1286    drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP: ui32DataInterleaveStatus %x\n", pContext->pMTXSetup->ui32DataInterleaveStatus);
1287    drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP: ui32TableA %x \n", pContext->pMTXSetup->ui32TableA);
1288    drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP:ui32ComponentsInScan %x\n", pContext->pMTXSetup->ui32ComponentsInScan);
1289    for (i32Lp = 0; i32Lp < 3; i32Lp++) {
1290        drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP: ComponentPlane[%d]: 0x%x, %d, %d\n",
1291                                 i32Lp, pContext->pMTXSetup->ComponentPlane[i32Lp].ui32PhysAddr, pContext->pMTXSetup->ComponentPlane[i32Lp].ui32Stride, pContext->pMTXSetup->ComponentPlane[i32Lp].ui32Height);
1292        drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP: MCUComponent[%d]: %d, %d, %d, %d\n", i32Lp, pContext->pMTXSetup->MCUComponent[i32Lp].ui32WidthBlocks, pContext->pMTXSetup->MCUComponent[i32Lp].ui32HeightBlocks, pContext->pMTXSetup->MCUComponent[i32Lp].ui32XLimit, pContext->pMTXSetup->MCUComponent[i32Lp].ui32YLimit);
1293    }
1294
1295    i32Lp = ctx->NumCores;
1296    while (--i32Lp > -1) {
1297        /*TOPAZ_InsertCommand(
1298                pEncContext,
1299                i32Lp,
1300                MTX_CMDID_SETUP,
1301                IMG_FALSE,
1302                IMG_NULL,
1303                pContext->pMemInfoMTXSetup );*/
1304
1305        pnw_cmdbuf_insert_command_package(ctx->obj_context,
1306                                          i32Lp,
1307                                          MTX_CMDID_SETUP,
1308                                          &(ctx->obj_context->pnw_cmdbuf->header_mem),
1309                                          0);
1310    }
1311
1312    return ReturnCode;
1313}
1314
1315#if 0
1316IMG_UINT32 Legacy_JPGEncodeSOSHeader(LEGACY_JPEG_ENCODER_CONTEXT *pContext, IMG_CODED_BUFFER *pCBuffer)
1317{
1318    IMG_UINT32  ui32TableIndex ;
1319    IMG_UINT8 uc_comp_id, ui8Comp;
1320    STREAMTYPEW s_streamW;
1321    IMG_UINT8 *puc_stream_buff;
1322
1323    puc_stream_buff = (IMG_UINT8 *)(pCBuffer->pMemInfo) + pCBuffer->ui32BytesWritten;
1324
1325    s_streamW.Offset = 0;
1326    s_streamW.Buffer = puc_stream_buff;
1327    s_streamW.Limit = (pCBuffer->ui32Size - pCBuffer->ui32BytesWritten);
1328
1329    /* Start of scan */
1330    fPutBitsToBuffer(&s_streamW, 2, START_OF_SCAN);
1331    /* Scan header length */
1332    fPutBitsToBuffer(&s_streamW, 2, 6 + (pContext->JPEGEncoderParams.uc_num_comp_in_scan << 1));
1333    /* Number of image components in scan */
1334    fPutBitsToBuffer(&s_streamW, 1, pContext->JPEGEncoderParams.uc_num_comp_in_scan);
1335
1336    if (pContext->JPEGEncoderParams.uc_num_comp_in_scan > MAX_COMP_IN_SCAN)
1337        pContext->JPEGEncoderParams.uc_num_comp_in_scan = MAX_COMP_IN_SCAN;
1338    for (ui8Comp = 0; ui8Comp < pContext->JPEGEncoderParams.uc_num_comp_in_scan; ui8Comp++) {
1339        uc_comp_id = pContext->JPEGEncoderParams.puc_comp_id[ui8Comp];
1340        if (uc_comp_id >= MAX_COMP_IN_SCAN) {
1341            drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalide component index %d\n", uc_comp_id);
1342            uc_comp_id = MAX_COMP_IN_SCAN - 1;
1343        }
1344
1345        ui32TableIndex  = pContext->sJPEGEncoderComp.CompIdtoIndex[uc_comp_id];
1346
1347        /* Scan component selector */
1348        fPutBitsToBuffer(&s_streamW, 1, uc_comp_id);
1349
1350        /*4 Bits Dc entropy coding table destination selector */
1351        /*4 Bits Ac entropy coding table destination selector */
1352        ui32TableIndex %= 255;
1353        fPutBitsToBuffer(&s_streamW, 1, (pContext->sJPEGEncoderComp.puc_huff_table_id[ui32TableIndex] << 4) | pContext->sJPEGEncoderComp.puc_huff_table_id[ui32TableIndex]);
1354    }
1355
1356    /* Start of spectral or predictor selection  */
1357    fPutBitsToBuffer(&s_streamW, 1, 0);
1358    /* End of spectral selection */
1359    fPutBitsToBuffer(&s_streamW, 1, 63);
1360    /*4 Bits Successive approximation bit position high (0)*/
1361    /*4 Bits Successive approximation bit position low or point transform (0)*/
1362    fPutBitsToBuffer(&s_streamW, 1, 0);
1363
1364    pCBuffer->ui32BytesWritten += s_streamW.Offset;
1365
1366    return 0;
1367}
1368#endif
1369
1370/***********************************************************************************
1371 * Function Name      : JPGEncodeSOSHeader
1372 * Inputs             : PContext - Pointer to JPEG context
1373 * Inputs             : pui8BitStreamBuffer start of the coded output buffer
1374 * Inputs             : pui32BytesWritten pointer to offset into the coded output buffer at which to write
1375 * Outputs            : pui8BitStreamBuffer - Start of Scan header written to the coded buffer
1376 * Returns            : Bytes writtren
1377 * Description        : This function writes the Start of Scan Header
1378 ************************************************************************************/
1379
1380IMG_UINT32 JPGEncodeSOSHeader(/*in */           TOPAZSC_JPEG_ENCODER_CONTEXT *pContext,
1381        /*out */        IMG_UINT8*              pui8BitStreamBuffer ,
1382        /*out*/         IMG_UINT32*             pui32BytesWritten)
1383{
1384    IMG_UINT8 uc_comp_id, ui8Comp;
1385    STREAMTYPEW s_streamW;
1386
1387    s_streamW.Offset = 0;
1388    s_streamW.Buffer = pui8BitStreamBuffer + *pui32BytesWritten;
1389
1390    /* Start of scan */
1391    fPutBitsToBuffer(&s_streamW, 2, START_OF_SCAN);
1392    /* Scan header length */
1393    fPutBitsToBuffer(&s_streamW, 2, 6 + (pContext->pMTXSetup->ui32ComponentsInScan << 1));
1394    /* Number of image components in scan */
1395    fPutBitsToBuffer(&s_streamW, 1, pContext->pMTXSetup->ui32ComponentsInScan);
1396    for (ui8Comp = 0; ui8Comp < pContext->pMTXSetup->ui32ComponentsInScan; ui8Comp++) {
1397        uc_comp_id = ui8Comp + 1;
1398
1399        /* Scan component selector */
1400        fPutBitsToBuffer(&s_streamW, 1, uc_comp_id);
1401
1402        /*4 Bits Dc entropy coding table destination selector */
1403        /*4 Bits Ac entropy coding table destination selector */
1404        fPutBitsToBuffer(&s_streamW, 1, ((ui8Comp != 0 ? 1 : 0) << 4) | (ui8Comp != 0 ? 1 : 0)); // Huffman table refs = 0 Luma 1 Chroma
1405    }
1406
1407    /* Start of spectral or predictor selection  */
1408    fPutBitsToBuffer(&s_streamW, 1, 0);
1409    /* End of spectral selection */
1410    fPutBitsToBuffer(&s_streamW, 1, 63);
1411    /*4 Bits Successive approximation bit position high (0)*/
1412    /*4 Bits Successive approximation bit position low or point transform (0)*/
1413    fPutBitsToBuffer(&s_streamW, 1, 0);
1414
1415    *pui32BytesWritten += s_streamW.Offset;
1416
1417    return 0;
1418}
1419
1420#if 0
1421/*****************************************************************************/
1422/*                                                                           */
1423/* Function Name : EncodeMJPEGAPP1Marker                                     */
1424/*                                                                           */
1425/* Description   : Writes a Quicktime MJPEG (A) marker                                       */
1426/*                                                                           */
1427/* Inputs        :                                                           */
1428/*                                      pContext                        - Ptr to the JPEG encoder context        */
1429/*                                      puc_stream_buff         - Ptr to the bistream buffer from        */
1430/*                                                                                      where to start writing                   */
1431/*                                                                           */
1432/* Processing    :                                                                                                                       */
1433/*                                                                           */
1434/* Returns       : Number of bytes written into the stream                   */
1435/*                                                                           */
1436/*****************************************************************************/
1437IMG_UINT32 Insert_QT_MJPEGA_APP1Marker(IMG_CODED_BUFFER *pCBuffer, IMG_UINT8 *pui8BitStreamBuffer, IMG_UINT32 ui32OffsetBytes, IMG_BOOL bIsFirstField)
1438{
1439    STREAMTYPEW ps_streamW;
1440#ifdef JPEG_VERBOSE
1441    printf("Insert_QT_MJPEGA_APP1Marker");
1442#endif
1443
1444    ps_streamW.Offset = 0;
1445    ps_streamW.Buffer = &pui8BitStreamBuffer[ui32OffsetBytes];
1446
1447    /* Writing the start of image marker */
1448    fPutBitsToBuffer(&ps_streamW, 2, START_OF_IMAGE);
1449    /* Writing the Motion-JPEG APP1 marker */
1450    fPutBitsToBuffer(&ps_streamW, 2, MJPEG_APP1);
1451    /* Marker content length */
1452    fPutBitsToBuffer(&ps_streamW, 2, 0x002A);
1453    /* Reserved, set to zero */
1454    fPutBitsToBuffer(&ps_streamW, 4, 0x00000000);
1455    /* Motion-JPEG tag = "mjpg"*/
1456    fPutBitsToBuffer(&ps_streamW, 4, 0x6D6A7067);
1457    /* Field size*/
1458    fPutBitsToBuffer(&ps_streamW, 4, pCBuffer->ui32BytesWritten + 2 - ui32OffsetBytes); // +2 because the EOI marker not written yet
1459    /* Padded Field size*/
1460    fPutBitsToBuffer(&ps_streamW, 4, pCBuffer->ui32BytesWritten + 2 - ui32OffsetBytes);
1461    /* Offset to next field*/
1462    if (bIsFirstField)
1463        fPutBitsToBuffer(&ps_streamW, 4, pCBuffer->ui32BytesWritten + 2 - ui32OffsetBytes); // Points to start of next field
1464    else
1465        fPutBitsToBuffer(&ps_streamW, 4, 0); // Set to zero for second field
1466
1467    /* Quantization Table Offset*/
1468    // May be able to leave this at zero
1469    fPutBitsToBuffer(&ps_streamW, 4, H_QT_OFFSET);
1470    /* Huffman Table Offset*/
1471    // May be able to leave this at zero
1472    fPutBitsToBuffer(&ps_streamW, 4, H_HT_OFFSET);
1473    /* Start Of Frame Offset*/
1474    fPutBitsToBuffer(&ps_streamW, 4, H_SOF_OFFSET);
1475    /* Start Of Scan Offset*/
1476    fPutBitsToBuffer(&ps_streamW, 4, H_SOS_OFFSET);
1477    /* Start of data offset*/
1478    fPutBitsToBuffer(&ps_streamW, 4, H_SOI_OFFSET);
1479
1480    return 0;
1481}
1482#endif
1483
1484/* JPEG Start picture function. Sets up all context information, Quantization details, Header output and MTX ready for the main encode loop*/
1485IMG_ERRORCODE SetupJPEGTables(TOPAZSC_JPEG_ENCODER_CONTEXT * pContext, IMG_CODED_BUFFER *pCBuffer,  object_surface_p pTFrame)
1486{
1487    /*IMG_UINT32 rc = 0;
1488    const IMG_UINT8* StandardQuantLuma;
1489    const IMG_UINT8* StandardQuantChroma;
1490    IMG_UINT8* QuantLumaTableOnHost;
1491    IMG_UINT8* QuantChromaTableOnHost;
1492    JPEG_MTX_QUANT_TABLE * psQuantTables;*/
1493    IMG_UINT16 ui16Lp;
1494    IMG_UINT8 ui8Planes[MAX_COMP_IN_SCAN];
1495    /*IMG_ENC_CONTEXT * pEncContext = (IMG_ENC_CONTEXT*)hEncContext;*/
1496    /*TOPAZSC_JPEG_ENCODER_CONTEXT * pContext = pEncContext->psJpegHC;*/
1497    IMG_INT8 i;
1498    context_ENC_p ctx = (context_ENC_p)pContext->ctx;
1499
1500    // Lets add a pointer from our context to the source surface structure (remember we still need to use GETBUFFER commands if we want to get shared image memory, but info data structures are on host)
1501    pContext->pSourceSurface = pTFrame;
1502
1503    //Try setting MCU details from here
1504    /*JPGEncodeBegin(pContext, pTFrame);*/
1505    InitializeJpegEncode(pContext, pTFrame);
1506
1507    // Special case for YUYV format
1508    if (ISCHROMAINTERLEAVED(pContext->eFormat) > C_INTERLEAVE)
1509        pContext->sScan_Encode_Info.ui32NumberMCUsX = (pContext->pMTXSetup->MCUComponent[0].ui32XLimit + ((pContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks * 2) - 1)) / (pContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks * 2);
1510    else
1511        pContext->sScan_Encode_Info.ui32NumberMCUsX = (pContext->pMTXSetup->MCUComponent[0].ui32XLimit + (pContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks - 1)) / pContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks;
1512
1513    pContext->sScan_Encode_Info.ui32NumberMCUsY = (pContext->pMTXSetup->MCUComponent[0].ui32YLimit + (pContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks - 1)) / pContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks;
1514    pContext->sScan_Encode_Info.ui32NumberMCUsToEncode = pContext->sScan_Encode_Info.ui32NumberMCUsX * pContext->sScan_Encode_Info.ui32NumberMCUsY;
1515
1516    pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan =
1517        JPEG_MCU_PER_SCAN(pContext->ui32OutputWidth, pContext->ui32OutputHeight, ctx->NumCores, pContext->eFormat);
1518
1519    drv_debug_msg(VIDEO_DEBUG_GENERAL, "MCUs To Encode %dx%d\n",
1520                             pContext->sScan_Encode_Info.ui32NumberMCUsX,
1521                             pContext->sScan_Encode_Info.ui32NumberMCUsY);
1522    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Total MCU %d, per scan %d\n", pContext->sScan_Encode_Info.ui32NumberMCUsToEncode, pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan);
1523
1524    //Allocate our coded data buffers here now we know the number of MCUs we're encoding
1525    /*Use slice parameter buffer*/
1526    if (AllocateCodedDataBuffers(pContext) != IMG_ERR_OK) return IMG_ERR_MEMORY;
1527    // Send Setup message to MTX to initialise it
1528    /*EncodeInitMTX(pEncContext);        Set predictors to zero */
1529
1530    for (i = ctx->NumCores - 1; i >= 0; i--) {
1531        pnw_cmdbuf_insert_command_package(
1532            ((context_ENC_p)pContext->ctx)->obj_context,
1533            i,
1534            MTX_CMDID_RESET_ENCODE,
1535            NULL,
1536            0);
1537    }
1538    //CODE HERE SIMPLIFIED AS WE KNOW THERE WILL ONLY EVER BE 3 IMAGE COMPONENTS
1539    /* Set up Source panes for HW */
1540    // Reverse colour plane pointers fed to MTX when required by format
1541
1542    switch (pContext->eFormat) {
1543    case IMG_CODEC_YV16:
1544        pContext->pMTXSetup->ComponentPlane[0].ui32Stride = pTFrame->psb_surface->stride;
1545        pContext->pMTXSetup->ComponentPlane[1].ui32Stride = pContext->pMTXSetup->ComponentPlane[0].ui32Stride / 2;
1546        pContext->pMTXSetup->ComponentPlane[2].ui32Stride = pContext->pMTXSetup->ComponentPlane[0].ui32Stride / 2;
1547
1548        pContext->pMTXSetup->ComponentPlane[0].ui32Height = pTFrame->height;
1549        pContext->pMTXSetup->ComponentPlane[1].ui32Height = pTFrame->height;
1550        pContext->pMTXSetup->ComponentPlane[2].ui32Height = pTFrame->height;
1551
1552        /*YV16's plane order is Y, V, U*/
1553        ui8Planes[0] = 0;
1554        ui8Planes[2] = 1;
1555        ui8Planes[1] = 2;
1556        break;
1557    case IMG_CODEC_IYUV:
1558    case IMG_CODEC_IMC2:
1559        /*case IMG_CODEC_422_IMC2:
1560            SetupYUVPlaneDetails(&(pContext->pMTXSetup->ComponentPlane[0]),
1561                    &(pTFrame->aui32ComponentInfo[0]));
1562
1563            SetupYUVPlaneDetails(&(pContext->pMTXSetup->ComponentPlane[2]),
1564                    &(pTFrame->aui32ComponentInfo[1]));
1565
1566            SetupYUVPlaneDetails(&(pContext->pMTXSetup->ComponentPlane[1]),
1567                    &(pTFrame->aui32ComponentInfo[2]));*/
1568        pContext->pMTXSetup->ComponentPlane[0].ui32Stride = pTFrame->psb_surface->stride;
1569        pContext->pMTXSetup->ComponentPlane[1].ui32Stride = pContext->pMTXSetup->ComponentPlane[0].ui32Stride / 2;
1570        pContext->pMTXSetup->ComponentPlane[2].ui32Stride = pContext->pMTXSetup->ComponentPlane[0].ui32Stride / 2;
1571
1572        pContext->pMTXSetup->ComponentPlane[0].ui32Height = pTFrame->height;
1573        pContext->pMTXSetup->ComponentPlane[1].ui32Height = pTFrame->height / 2;
1574        pContext->pMTXSetup->ComponentPlane[2].ui32Height = pTFrame->height / 2;
1575
1576        //ui8Planes[0]=0;ui8Planes[1]=2;ui8Planes[2]=1;
1577        /*IYUV don't need to swap UV color space. Not sure about IMC12*/
1578        ui8Planes[0] = 0;
1579        ui8Planes[1] = 1;
1580        ui8Planes[2] = 2;
1581        break;
1582    default:
1583        /*SetupYUVPlaneDetails(&(pContext->pMTXSetup->ComponentPlane[0]),
1584            &(pTFrame->aui32ComponentInfo[0]));
1585
1586        SetupYUVPlaneDetails(&(pContext->pMTXSetup->ComponentPlane[1]),
1587            &(pTFrame->aui32ComponentInfo[1]));
1588
1589        SetupYUVPlaneDetails(&(pContext->pMTXSetup->ComponentPlane[2]),
1590            &(pTFrame->aui32ComponentInfo[2]));*/
1591        /* It's for NV12*/
1592        pContext->pMTXSetup->ComponentPlane[0].ui32Stride = pTFrame->psb_surface->stride;
1593        pContext->pMTXSetup->ComponentPlane[1].ui32Stride = pContext->pMTXSetup->ComponentPlane[0].ui32Stride;
1594        pContext->pMTXSetup->ComponentPlane[2].ui32Stride = pContext->pMTXSetup->ComponentPlane[0].ui32Stride;
1595
1596        pContext->pMTXSetup->ComponentPlane[0].ui32Height = pTFrame->height;
1597        pContext->pMTXSetup->ComponentPlane[1].ui32Height = pTFrame->height / 2;
1598        pContext->pMTXSetup->ComponentPlane[2].ui32Height = pTFrame->height / 2;
1599
1600        ui8Planes[0] = 0;
1601        ui8Planes[1] = 1;
1602        ui8Planes[2] = 2;
1603        break;
1604    };
1605
1606
1607    SetupIssueSetup(pContext, pContext->pMTXSetup->ui32ComponentsInScan, ui8Planes, pTFrame, 0 , 1);
1608
1609    if (pContext->pMTXSetup->ui32ComponentsInScan > MAX_COMP_IN_SCAN) {
1610        return IMG_ERR_UNDEFINED;
1611    }
1612
1613    if ((pCBuffer->ui32Size - pCBuffer->ui32BytesWritten) < 9 + 6 + (4 *(IMG_UINT32)pContext->pMTXSetup->ui32ComponentsInScan)) {
1614        return  IMG_ERR_MEMORY;
1615    }
1616
1617    // Reset Scan Encode structures - just in case
1618    for (ui16Lp = 0; ui16Lp < pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers; ui16Lp++) {
1619        BUFFER_HEADER *pbh;
1620
1621        pContext->sScan_Encode_Info.aBufferTable[ui16Lp].i8MTXNumber = 0; // Indicates buffer is idle
1622        pContext->sScan_Encode_Info.aBufferTable[ui16Lp].ui16ScanNumber = 0; // Indicates buffer is idle
1623
1624        pContext->sScan_Encode_Info.aBufferTable[ui16Lp].ui32DataBufferUsedBytes = 0;
1625
1626        //pbh = MMGetHostLinAddress(pContext->sScan_Encode_Info.aBufferTable[ui16Lp].pMemInfo );
1627        pbh = (BUFFER_HEADER *)(pContext->sScan_Encode_Info.aBufferTable[ui16Lp].pMemInfo);
1628        pbh->ui32BytesEncoded = 0;
1629        pbh->ui32BytesUsed = sizeof(BUFFER_HEADER);
1630    }
1631
1632    //Prefill out MTXIdleTable with MTX references (0 is the Master, and will be the last sent)
1633    for (pContext->sScan_Encode_Info.ui8MTXIdleCnt = 0; pContext->sScan_Encode_Info.ui8MTXIdleCnt < ctx->NumCores; pContext->sScan_Encode_Info.ui8MTXIdleCnt++) {
1634        pContext->sScan_Encode_Info.aui8MTXIdleTable[pContext->sScan_Encode_Info.ui8MTXIdleCnt] = pContext->sScan_Encode_Info.ui8MTXIdleCnt + 1;
1635    }
1636
1637
1638    //Need to set up CB Output slicenumber to equal number of slices required to encode image
1639    // Set current CB scan to maximum scan number (will count down as scans are output)
1640    pContext->sScan_Encode_Info.ui16CScan = (pContext->sScan_Encode_Info.ui32NumberMCUsToEncode + (pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan - 1)) / pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan;
1641    pContext->sScan_Encode_Info.ui16ScansInImage = pContext->sScan_Encode_Info.ui16CScan;
1642    // Set next scan to send to MTX to maximum scan number
1643    pContext->sScan_Encode_Info.ui16SScan = pContext->sScan_Encode_Info.ui16CScan;
1644    pContext->ui32InitialCBOffset = 0;
1645
1646    return IMG_ERR_OK;
1647}
1648
1649#if 0
1650IMG_ERRORCODE Legacy_PrepareHeader(LEGACY_JPEG_ENCODER_CONTEXT * pContext, IMG_CODED_BUFFER *pCBuffer)
1651{
1652    IMG_ERRORCODE rc;
1653    IMG_UINT8 *ui8OutputBuffer;
1654
1655    ui8OutputBuffer = pCBuffer->pMemInfo;
1656    //Lock our JPEG Coded buffer
1657    /* if (IMG_JPEG_GetBuffer(pCBuffer, (IMG_VOID **) &ui8OutputBuffer)!=IMG_ERR_OK)
1658     return IMG_ERR_SURFACE_LOCKED;*/
1659
1660    pCBuffer->ui32BytesWritten = 0;
1661    *((IMG_UINT32*) ui8OutputBuffer) = 0;
1662
1663    // JPGEncodeMarker - Currently misses out the APP0 header
1664    rc = Legacy_JPGEncodeMarker(pContext, (IMG_UINT8 *) ui8OutputBuffer,  &pCBuffer->ui32BytesWritten);
1665    if (rc) return rc;
1666
1667    rc = Legacy_JPGEncodeHeader(pContext , (IMG_UINT8 *) ui8OutputBuffer ,  &pCBuffer->ui32BytesWritten);
1668    if (rc) return rc;
1669
1670    //  JPGEncodeDRIMarker(pContext,pCBuffer);
1671    Legacy_JPGEncodeSOSHeader(pContext, pCBuffer);
1672
1673    //IMG_JPEG_ReleaseBuffer( pCBuffer);
1674
1675
1676    return IMG_ERR_OK;
1677}
1678/* Send header will work for each type of header*/
1679#endif
1680
1681/***********************************************************************************
1682 * Function Name      : PrepareHeader
1683 * Inputs             : Pointer to JPEG Context, Point to coded buffer
1684 * Outputs            :
1685 * Returns            : IMG_ERRORCODE
1686 * Description        : Writes required JPEG Header elements to the coded buffer
1687 ************************************************************************************/
1688IMG_ERRORCODE PrepareHeader(TOPAZSC_JPEG_ENCODER_CONTEXT * pContext, IMG_CODED_BUFFER *pCBuffer, IMG_UINT32 ui32StartOffset, IMG_BOOL bIncludeHuffmanTables)
1689{
1690    IMG_ERRORCODE rc;
1691    IMG_UINT8 *ui8OutputBuffer;
1692
1693    //Lock our JPEG Coded buffer
1694    /*if (IMG_C_GetBuffer((IMG_HENC_CONTEXT) pContext, pCBuffer, (IMG_VOID **) &ui8OutputBuffer)!=IMG_ERR_OK)
1695    return IMG_ERR_SURFACE_LOCKED;*/
1696
1697    ui8OutputBuffer = (IMG_UINT8 *)pCBuffer->pMemInfo;
1698    pCBuffer->ui32BytesWritten = ui32StartOffset;
1699    *((IMG_UINT32*) ui8OutputBuffer + pCBuffer->ui32BytesWritten) = 0;
1700
1701
1702    // JPGEncodeMarker - Currently misses out the APP0 header
1703    rc = JPGEncodeMarker(pContext, (IMG_UINT8 *) ui8OutputBuffer,  &pCBuffer->ui32BytesWritten, bIncludeHuffmanTables);
1704    if (rc) return rc;
1705
1706    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Current bytes of coded buf used: %d\n", pCBuffer->ui32BytesWritten);
1707    rc = JPGEncodeHeader(pContext , (IMG_UINT8 *) ui8OutputBuffer ,  &pCBuffer->ui32BytesWritten);
1708    if (rc) return rc;
1709
1710    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Current bytes of coded buf used: %d\n", pCBuffer->ui32BytesWritten);
1711    rc = JPGEncodeSOSHeader(pContext, (IMG_UINT8 *) ui8OutputBuffer, &pCBuffer->ui32BytesWritten);
1712    if (rc) return rc;
1713
1714    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Current bytes of coded buf used: %d\n", pCBuffer->ui32BytesWritten);
1715    /*IMG_C_ReleaseBuffer((IMG_HENC_CONTEXT) pContext, pCBuffer);*/
1716    return IMG_ERR_OK;
1717}
1718
1719
1720
1721
1722/***********************************************************************************
1723 * Function Name      : IMG_JPEG_ISSUEBUFFERTOHW
1724 * Inputs             :
1725 * Outputs            : pui32MCUsToProccess
1726 * Returns            :
1727 * Description        : Issues a buffer to MTX to recieve coded data.
1728 *
1729 ************************************************************************************/
1730
1731IMG_ERRORCODE IssueBufferToHW(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext, TOPAZSC_JPEG_BUFFER_INFO* pWriteBuf, IMG_UINT16 ui16BCnt, IMG_UINT32 ui32NoMCUsToEncode, IMG_INT8 i8MTXNumber)
1732{
1733    MTX_ISSUE_BUFFERS *psBufferCmd;
1734    context_ENC_p ctx = (context_ENC_p)pContext->ctx;
1735    /*IMG_ENC_CONTEXT * pEncContext = (IMG_ENC_CONTEXT*)hContext;
1736    TOPAZSC_JPEG_ENCODER_CONTEXT *pContext = pEncContext->psJpegHC;*/
1737
1738#ifdef JPEG_VERBOSE
1739    printf("\n**************************************************************************\n");
1740    printf("** HOST SENDING Scan:%i (%i MCUs) to MTX %i, using Buffer %i\n", pWriteBuf->ui16ScanNumber, ui32NoMCUsToEncode, i8MTXNumber - 1, ui16BCnt);
1741#endif
1742    drv_debug_msg(VIDEO_DEBUG_GENERAL, "HOST SENDING Scan:%d (%d MCUs, offset %d MCUs)"
1743                             " to MTX %d, using Buffer %d\n",
1744                             pWriteBuf->ui16ScanNumber, ui32NoMCUsToEncode,
1745                             pContext->sScan_Encode_Info.ui32CurMCUsOffset,
1746                             i8MTXNumber, ui16BCnt);
1747
1748    // Issue to MTX ////////////////////////////
1749    ASSERT(pWriteBuf->pMemInfo);
1750
1751    // Lets send our input parameters using the device memory allocated for the coded output
1752    psBufferCmd = (MTX_ISSUE_BUFFERS *)(pWriteBuf->pMemInfo);
1753
1754    // We've disabled size bound checking in firmware, so can use the full 31 bits for NoMCUsToEncode instead
1755    //psBufferCmd->ui32MCUCntAndResetFlag       = ( DATA_BUFFER_SIZE(pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan) << 16) | (ui32NoMCUsToEncode << 1) | 0x1;
1756
1757    psBufferCmd->ui32MCUCntAndResetFlag = (ui32NoMCUsToEncode << 1) | 0x1;
1758    psBufferCmd->ui32CurrentMTXScanMCUPosition = pContext->sScan_Encode_Info.ui32CurMCUsOffset;
1759    drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP: ui32MCUCntAndResetFlag 0x%x\n", psBufferCmd->ui32MCUCntAndResetFlag);
1760    drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ_PDUMP: ui32CurrentMTXScanMCUPosition 0x%x\n", psBufferCmd->ui32CurrentMTXScanMCUPosition);
1761    /* We do not need to do this but in order for params to match on HW we need to know whats in the buffer*/
1762    /*MMUpdateDeviceMemory(pWriteBuf->pMemInfo );*/
1763
1764    /*TOPAZ_InsertCommand(
1765        pEncContext,
1766        (IMG_INT32) (i8MTXNumber-1),
1767        MTX_CMDID_ISSUEBUFF,
1768        IMG_FALSE,
1769        &pWriteBuf->ui32WriteBackVal,
1770        pWriteBuf->pMemInfo );*/
1771    pnw_cmdbuf_insert_command_package(ctx->obj_context,
1772                                      (IMG_INT32)(i8MTXNumber) ,
1773                                      MTX_CMDID_ISSUEBUFF,
1774                                      ctx->coded_buf->psb_buffer,
1775                                      ui16BCnt * pContext->ui32SizePerCodedBuffer + PNW_JPEG_HEADER_MAX_SIZE);
1776
1777    return IMG_ERR_OK;
1778}
1779
1780/***********************************************************************************
1781 * Function Name      : SubmitScanToMTX
1782 * Inputs             :
1783 *                                              pContext - Pointer to JPEG context
1784 *                                              ui16BCnt - Index of the buffer to associate with the MTX
1785 *                                              i8MTXNumber - The ID number of the MTX that will have a scan sent to it
1786 * Outputs            : Status update to current buffer, MTX is activated
1787 * Returns            : Errorcode
1788 * Description        : Associates the empty buffer with the inactive MTX and then
1789 *                                              starts a scan, with output to be sent to the buffer.
1790 ************************************************************************************/
1791
1792IMG_ERRORCODE SubmitScanToMTX(TOPAZSC_JPEG_ENCODER_CONTEXT *pContext,
1793                              IMG_UINT16 ui16BCnt,
1794                              IMG_INT8 i8MTXNumber,
1795                              IMG_UINT32 ui32NoMCUsToEncode)
1796{
1797    /*IMG_ENC_CONTEXT * pEncContext = (IMG_ENC_CONTEXT*)hContext;
1798    TOPAZSC_JPEG_ENCODER_CONTEXT *pContext = pEncContext->psJpegHC;*/
1799
1800
1801#if 0
1802    // Submit a scan and buffer to the appropriate MTX unit
1803    IMG_UINT32 ui32NoMCUsToEncode;
1804
1805    if (pContext->sScan_Encode_Info.ui16SScan == 0) {
1806        // Final scan, may need fewer MCUs than buffer size, calculate the remainder
1807        ui32NoMCUsToEncode = pContext->sScan_Encode_Info.ui32NumberMCUsToEncode % pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan;
1808        if (ui32NoMCUsToEncode == 0)    ui32NoMCUsToEncode = pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan;
1809    } else
1810        ui32NoMCUsToEncode = pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan;
1811#endif
1812    //Set the buffer returned size to -1
1813    pContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui32DataBufferUsedBytes = ((BUFFER_HEADER*)(pContext->sScan_Encode_Info.aBufferTable[ui16BCnt].pMemInfo))->ui32BytesUsed = -1; // Won't be necessary with SC Peek commands enabled
1814    IssueBufferToHW(pContext, &(pContext->sScan_Encode_Info.aBufferTable[ui16BCnt]), ui16BCnt, ui32NoMCUsToEncode, i8MTXNumber);
1815
1816    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Submitting scan %i to MTX %i and Buffer %i\n", pContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui16ScanNumber, i8MTXNumber, ui16BCnt);
1817    return IMG_ERR_OK;
1818}
1819
1820
1821void pnw_jpeg_set_default_qmatix(unsigned char *pMemInfoTableBlock)
1822{
1823    JPEG_MTX_QUANT_TABLE *pQTable = (JPEG_MTX_QUANT_TABLE *)pMemInfoTableBlock;
1824    memcpy(pQTable->aui8LumaQuantParams, gQuantLuma, QUANT_TABLE_SIZE_BYTES);
1825    memcpy(pQTable->aui8ChromaQuantParams, gQuantChroma, QUANT_TABLE_SIZE_BYTES);
1826    return;
1827}
1828