mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-24 09:14:09 +08:00
improve logic of __mg_check_jpg for performance .
loop for reading JPEG marker from MG_RWops object,if meet other JPEG marker(eg. SOI,APPn,DQT) skip the payload bytes for next marker,until reach SOF0 or SOF2. about JPEG marker, see also https://en.wikipedia.org/wiki/JPEG
This commit is contained in:
+69
-65
@@ -254,10 +254,37 @@ static void my_error_exit (j_common_ptr cinfo)
|
||||
longjmp (myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common JPEG markers
|
||||
* see also https://en.wikipedia.org/wiki/JPEG
|
||||
* */
|
||||
#define JMK_SOI 0xFFD8 /* Start Of Image */
|
||||
#define JMK_SOF0 0xFFC0 /* Start Of Frame (baseline DCT) */
|
||||
#define JMK_SOF2 0xFFC2 /* Start Of Frame (progressive DCT) */
|
||||
#define JMK_DHT 0xFFC4 /* Define Huffman Table(s) */
|
||||
#define JMK_DQT 0xFFDB /* Define Quantization Table(s) */
|
||||
#define JMK_DRI 0xFFDD /* Define Restart Interval */
|
||||
#define JMK_SOS 0xFFDA /* Start Of Scan */
|
||||
#define JMK_RST_mask 0xFFD0 /* mask of Restart */
|
||||
#define JMK_APP_mask 0xFFE0 /* mask of Application-specific */
|
||||
#define JMK_COM 0xFFFE /* Comment */
|
||||
#define JMK_EOI 0xFFD9 /* End Of Image */
|
||||
/**
|
||||
* Reads a 16-bit big endian integer from a MG_RWops object.
|
||||
* return TRUE if sucess,or FALSE if the read failed.
|
||||
*/
|
||||
static BOOL read_be16 (MG_RWops *fp,Uint16 *value)
|
||||
{
|
||||
if(-1 == MGUI_RWread(fp, value, (sizeof *value), 1))
|
||||
return FALSE;
|
||||
*value = (ArchSwapBE16(*value));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal)
|
||||
{
|
||||
int i;
|
||||
unsigned char magic[5];
|
||||
Uint16 soi_marker;
|
||||
|
||||
/* This struct contains the JPEG decompression parameters
|
||||
* and pointers to working space
|
||||
@@ -267,11 +294,8 @@ void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal)
|
||||
struct my_error_mgr *jerr;
|
||||
jpeg_init_info_t* init_info;
|
||||
|
||||
if (!MGUI_RWread (fp, magic, 2, 1))
|
||||
goto err; /* not JPEG image*/
|
||||
if (magic[0] != 0xFF || magic[1] != 0xD8)
|
||||
goto err; /* not JPEG image*/
|
||||
|
||||
if(!read_be16(fp,&soi_marker) || JMK_SOI != soi_marker )
|
||||
goto err; /* not JPEG image*/
|
||||
|
||||
MGUI_RWseek (fp, 0, SEEK_SET);
|
||||
|
||||
@@ -446,68 +470,48 @@ int __mg_load_jpg (MG_RWops* fp, void* init_info, MYBITMAP *my_bmp,
|
||||
return ERR_BMP_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loop read JPEG marker from MG_RWops object,until reach SOF0 or SOF2.
|
||||
* return TRUE if match JPEG image format,or FALSE if the read failed or not JPEG image
|
||||
*/
|
||||
BOOL __mg_check_jpg (MG_RWops* fp)
|
||||
{
|
||||
unsigned char magic [5];
|
||||
|
||||
if (!MGUI_RWread (fp, magic, 2, 1))
|
||||
return FALSE; /* not JPEG image*/
|
||||
if (magic[0] != 0xFF || magic[1] != 0xD8)
|
||||
return FALSE; /* not JPEG image*/
|
||||
|
||||
MGUI_RWseek (fp, 0, SEEK_SET);
|
||||
|
||||
/* This struct contains the JPEG decompression parameters
|
||||
* and pointers to working space
|
||||
* (which is allocated as needed by the JPEG library).
|
||||
*/
|
||||
struct jpeg_decompress_struct *cinfo;
|
||||
struct my_error_mgr *jerr;
|
||||
jpeg_init_info_t* init_info;
|
||||
|
||||
/* Step 1: allocate and initialize JPEG decompression object */
|
||||
cinfo = calloc (1, sizeof(struct jpeg_decompress_struct));
|
||||
jerr = calloc (1, sizeof(struct my_error_mgr));
|
||||
init_info = calloc (1, sizeof(jpeg_init_info_t));
|
||||
|
||||
if (cinfo == NULL || jerr == NULL || init_info == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* We set up the normal JPEG error routines first. */
|
||||
cinfo->err = jpeg_std_error (&jerr->pub);
|
||||
jerr->pub.error_exit = my_error_exit;
|
||||
|
||||
|
||||
/* return value*/
|
||||
BOOL ret = TRUE;
|
||||
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
if (setjmp (jerr->setjmp_buffer))
|
||||
{
|
||||
/* If we get here, the JPEG code has signaled an error */
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
for(Uint16 jpeg_marker;read_be16(fp,&jpeg_marker) /* read JPEG marker */;){
|
||||
/* payload length of current marker */
|
||||
Uint16 payload = 1; /* set 1 for default, mean that current marker followed by payload bytes*/
|
||||
switch(jpeg_marker)
|
||||
{
|
||||
case JMK_SOI:
|
||||
payload = 0; /* no payload */
|
||||
break;
|
||||
case JMK_SOF0:
|
||||
case JMK_SOF2:
|
||||
return TRUE; /* JPEG image*/
|
||||
case JMK_DHT:
|
||||
case JMK_DQT:
|
||||
case JMK_DRI:
|
||||
case JMK_SOS:
|
||||
case JMK_COM:
|
||||
break;
|
||||
case JMK_EOI:
|
||||
return FALSE; /* not JPEG image*/
|
||||
default:
|
||||
if((0XFFF8 & jpeg_marker) == JMK_RST_mask){
|
||||
payload = 0; /* RST0~7(FFD0~FFD7),no payload */
|
||||
}else if((0XFFF0 & jpeg_marker) == JMK_APP_mask){
|
||||
/* APP0~APP15,do nothing */
|
||||
}else
|
||||
return FALSE; /* not JPEG image*/
|
||||
}
|
||||
if(payload){
|
||||
/*read payload length and skip next marker */
|
||||
if(!read_be16(fp,&payload))
|
||||
return FALSE; /* not JPEG image*/
|
||||
MGUI_RWseek (fp, payload- sizeof(payload), SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we can initialize the JPEG decompression object. */
|
||||
jpeg_create_decompress (cinfo);
|
||||
init_info->dec_started = 0;
|
||||
|
||||
/* Step 2: specify data source */
|
||||
my_jpeg_data_src (cinfo, fp);
|
||||
|
||||
/* Step 3: read file parameters with jpeg_read_header() */
|
||||
if(JPEG_HEADER_OK != jpeg_read_header (cinfo, TRUE))
|
||||
{
|
||||
longjmp (jerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
end:
|
||||
jpeg_destroy_decompress (cinfo);
|
||||
free (init_info);
|
||||
free (jerr);
|
||||
free (cinfo);
|
||||
return ret;
|
||||
return FALSE; /* not JPEG image*/
|
||||
}
|
||||
|
||||
#endif /* _MGIMAGE_JPG */
|
||||
|
||||
Reference in New Issue
Block a user