📄 png_decoder.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
* Filename:
* ---------
* png_decoder.c
*
* Project:
* --------
* MAUI
*
* Description:
* ------------
* Driver of the png decoder .
*
* Author:
* -------
* -------
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
// include header files
#include "kal_release.h"
#include "reg_base.h"
#include "intrCtrl.h"
#include "drv_comm.h"
#include "gpt_sw.h"
#include "visual_comm.h"
#include "drm_gprot.h"
#include "fat_fs.h"
#include "bytestream_hw.h"
#include "png_decoder.h"
#include "2d_engine.h"
#include "visualhisr.h"
// #define USE_HW_PNG_DECODER
#if defined(USE_HW_PNG_DECODER_V1)
static png_dcb_struct png_dcb;
static png_state_enum png_state;
static VISUAL_HISR_ID png_hisr;
static kal_uint8 png_gpt_handle;
// constant
#define PNG_IDAT_BUF_LEN 8*1024
static kal_uint8 png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
static const kal_uint8 png_IHDR[5] = { 73, 72, 68, 82, '\0'};
static const kal_uint8 png_IDAT[5] = { 73, 68, 65, 84, '\0'};
static const kal_uint8 png_IEND[5] = { 73, 69, 78, 68, '\0'};
static const kal_uint8 png_PLTE[5] = { 80, 76, 84, 69, '\0'};
static const kal_uint8 png_tRNS[5] = {116, 82, 78, 83, '\0'};
static const kal_uint8 png_bKGD[5] = { 98, 75, 71, 68, '\0'};
#define DONT_CARE 1
static const kal_uint8 png_type_channel[] = {1,DONT_CARE,3,1,2,DONT_CARE,4};
static kal_uint32 png_idat_buf[PNG_IDAT_BUF_LEN/4+1];
static kal_uint32 idat_buf_len = PNG_IDAT_BUF_LEN;
/*************************************************************************
* FUNCTION
* png_assemble_idat
*
* DESCRIPTION
* 1. assemle the IDAT chunk into png_idat_buf
* 2. check if the last IDAT is reached
* 3. there are two special case: a. only one data chunk and less than 4 bytes
* b. the last remaining bytes are less than 4 bytes
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
* png_dcb.my_idat_remain
*
*************************************************************************/
static void png_assemble_idat(void)
{
kal_uint32 remain,len,size;
kal_uint8 *ptr = (kal_uint8*)png_idat_buf;
kal_uint8 buf[4];
remain = png_dcb.my_idat_remain ;
size = idat_buf_len;
while(1)
{
if(remain)
{
len = remain;
goto no_header;
}
else
{
// encounter a new IDAT chunk
len = PNG_GET_U32();
if(len > 0x1000000)
PNG_RAISE(1);
PNG_GET_ARRAY(buf, 4);
}
if(!kal_mem_cmp(buf,png_IDAT,4) && len!=0)
{
no_header:
if(size >= len)
{
// read entire IDAT chunk into buffer
PNG_GET_ARRAY(ptr, len);
PNG_FLUSH(4);// crc
size -= len;
ptr += len;
remain = 0;
}
else if(size > 0)
{
// fill the idat buffer and record the remaining IDAT bytes
PNG_GET_ARRAY(ptr, size);
remain = len -size;
png_dcb.my_idat_remain = remain;
break;
}
else if (size == 0)
{
png_dcb.my_idat_remain = len;
break;
}
}
else
{
// all IDAT is finished
png_dcb.z_count = ptr - (kal_uint8*)png_idat_buf;
png_dcb.is_IEND = KAL_TRUE;
break;
}
}
}
/*************************************************************************
* FUNCTION
* png_remove_srckey_color
*
* DESCRIPTION
* modify the same color with the transparent index
*
* PARAMETERS
* index: transparent index
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
/*static void png_remove_srckey_color( kal_uint32 index)
{
kal_uint32 i,count;
kal_uint32 src_key;
kal_uint32 *ct = png_dcb.cfg->color_table;
src_key = ct[index];
count = png_dcb.info.num_plte;
for(i=0;i<=count;i++)
{
if(src_key == ct[i])
{
// modify the blue
ct[i] ^= 1;
}
}
ct[index]= src_key;
}*/
/*************************************************************************
* FUNCTION
* png_timeout_hander
*
* DESCRIPTION
* call back function of the GPT timer ot handle the decoding timeout.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
static void png_timeout_hander(void* p)
{
png_dcb.is_timeout = KAL_TRUE;
kal_print("hw png decode timeout");
DRV_WriteReg32(PNG_IRQ_EN, 0);
PNG_RESET();
png_state = PNG_STATE_READY;
DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_PNG,PDN_PNG);
if(png_dcb.cb != NULL)
png_dcb.cb(PNG_DECODE_TIMEOUT);
}
/*************************************************************************
* FUNCTION
* png_resz_ratio
*
* DESCRIPTION
* calculate the resizing ratio according to the real size and expected one
*
* PARAMETERS
* real: actual image width or height
* expect: expected image width or height
*
* RETURNS
* The resizing ratio
*
* GLOBALS AFFECTED
*
*************************************************************************/
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
/*************************************************************************
* FUNCTION
* png_g2d_bitblt
*
* DESCRIPTION
* bitblit the png_work_buffer onto the destination LCD frame buffer.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
/*************************************************************************
* FUNCTION
* png_get_gray_scale
*
* DESCRIPTION
* 1. Transform the gray value from low bit depth into 8 bit depth
* 2. Transfrom the 16-bepth gray value into 8-bit depth.
* PARAMETERS
* bit_depth: original bit depth of the gray value
* gray: gray value to be transformed.
*
* RETURNS
* The transformed 8-bit gray value.
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint32 png_get_gray_scale(kal_uint32 bit_depth, kal_uint32 gray)
{
kal_uint32 loop,value;
ASSERT(gray <= ((1<<bit_depth)-1));
if(gray == ((1<<bit_depth)-1))
return 0xff;
if(gray == 0)
return gray;
if(bit_depth < 8)
{
value = gray;
loop = (8/bit_depth) -1 ;
while(loop--)
{
value = (value << bit_depth);
value |= gray;
}
return value;
}
else if(bit_depth == 8)
{
return gray;
}
else
{
return gray >> 8;
}
}
/*************************************************************************
* FUNCTION
* png_decode_hw
*
* DESCRIPTION
* 1. start to decode the specific PNG image (first time of a image)
* 2. input all of the registers of png decoder
* 3. trigger the decoding process
*
* PARAMETERS
* z_len: length of IDAT count
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
// len: length of IDAT count
static void png_decode_hw(kal_uint32 z_len)
{
register png_config_struct *cfg = png_dcb.cfg;
png_inform_struct *info = &png_dcb.info;
kal_uint32 reg,out_format;
kal_uint8 resz_w=0, resz_h=0;
DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_PNG,PDN_PNG);
DRV_WriteReg32(PNG_IRQ_EN, 0);
PNG_RESET();
png_dcb.my_idat_remain = z_len;
png_assemble_idat();
DRV_WriteReg32(PNG_IN_START, png_idat_buf);
DRV_WriteReg32(PNG_IN_COUNT, idat_buf_len+4);
if(png_dcb.z_count >= 4)
{
DRV_WriteReg32(PNG_IDAT_COUNT, png_dcb.z_count);
}
else if(png_dcb.z_count > 0)
{
kal_uint32 reg,i;
kal_uint8 *ptr = (kal_uint8*)png_idat_buf;
for(reg=0,i=0; i<png_dcb.z_count; i++)
{
reg |= (ptr[i] << (8*i));
}
DRV_WriteReg32(PNG_IDAT_BUFFER, reg);
DRV_WriteReg32(PNG_IDAT_COUNT, png_dcb.z_count);
}
else
DRV_WriteReg32(PNG_IDAT_COUNT, idat_buf_len);
// configure the buffers
#if defined(PNG_NEW_BUFFER_INTERFACE)
{
register kal_uint32 buf_index;
buf_index = (kal_uint32)cfg->color_table_t;
buf_index += CT_LEN*4;
DRV_WriteReg32(PNG_HCLEN_START, buf_index);
buf_index += HCLEN_LEN;
DRV_WriteReg32(PNG_HLEN_START, buf_index);
buf_index += HLEN_LEN;
DRV_WriteReg32(PNG_HLIT_START, buf_index);
buf_index += HLIT_LEN;
DRV_WriteReg32(PNG_HDIST_START, buf_index);
buf_index += HDIST_LEN;
DRV_WriteReg32(PNG_BUFF0_START, buf_index);
buf_index += BUFF0_LEN;
DRV_WriteReg32(PNG_BUFF1_START, buf_index);
buf_index += BUFF1_LEN;
DRV_WriteReg32(PNG_LZ77_START, buf_index);
}
#else
DRV_WriteReg32(PNG_HCLEN_START, cfg->hclen);
DRV_WriteReg32(PNG_HLEN_START, cfg->hlen);
DRV_WriteReg32(PNG_HLIT_START, cfg->hlit);
DRV_WriteReg32(PNG_HDIST_START, cfg->hdist);
DRV_WriteReg32(PNG_BUFF0_START, cfg->buff0);
DRV_WriteReg32(PNG_BUFF1_START, cfg->buff1);
DRV_WriteReg32(PNG_LZ77_START, cfg->LZ77);
#endif
DRV_WriteReg32(PNG_CT_START, cfg->color_table);
DRV_WriteReg32(PNG_TRAN_TABLE, cfg->color_table_t);
reg = (info->bit_depth << 3)|(info->color_type);
DRV_WriteReg8(PNG_COLOR_TYPE, reg);
DRV_WriteReg8(PNG_INTERLACE_EN, info->interlaced);
DRV_WriteReg32(PNG_IMG_WH, (info->img_w << 16) | info->img_h);
// partial input have to be enabled always
out_format = cfg->out_format|PNG_OUT_FORMAT_PATRIAL;
// use software to remove MMI's source key
if((info->color_type == COLOR_TYPE_RGB || info->color_type == COLOR_TYPE_RGB_A)
&&(cfg->out_format == RGB565|| cfg->out_format == RGB888))
info->use_work_buf = KAL_TRUE;
// calculate resz_w , resz_h
{
kal_uint32 bytes_per_pixel;
switch(cfg->out_format)
{
case RGB565: bytes_per_pixel=2;break;
case RGB888: bytes_per_pixel=3;break;
case ARGB8888: bytes_per_pixel=4;break;
default: bytes_per_pixel=1;break;
}
if(cfg->expect_w==0) cfg->expect_w = info->img_w;
if(cfg->expect_h==0) cfg->expect_h = info->img_h;
cfg->cal_work_buffer_info_func(
&resz_w,
&info->wb_dest_x,&info->wb_dest_y,
&info->wb_width,&info->wb_height,
cfg->work_buffer_size / bytes_per_pixel,
info->img_w,info->img_h,
cfg->dest_x,cfg->dest_y,
cfg->expect_w,cfg->expect_h,
cfg->clip_x1,cfg->clip_y1,cfg->clip_x2,cfg->clip_y2);
resz_h = resz_w;
}
info->use_work_buf = KAL_FALSE;
info->resz_w = resz_w;
info->resz_h = resz_h;
// configure the resizing
if((info->img_w>>resz_w) != cfg->expect_w
||(info->img_h>>resz_h)!= cfg->expect_h)
{
// use 2D engine to perform transparent
info->use_work_buf = KAL_TRUE;
}
if(resz_w || resz_h)
{ // use software resizer to perform fine resizing
png_dcb.resz_en = KAL_TRUE;
png_dcb.resz_w = resz_w;
png_dcb.resz_h = resz_h;
reg = (resz_w << 8)|(resz_h << 4)|1;
DRV_WriteReg32(PNG_RESIZE_CTRL, reg);
}
else
{
DRV_WriteReg32(PNG_RESIZE_CTRL, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -