* Optimize JPEG scaling by downscaling as much as possible during decompression.

This commit is contained in:
Justin Maggard 2010-06-08 17:34:29 +00:00
parent 20bb1db8a7
commit c779eab4de
6 changed files with 33 additions and 19 deletions

View File

@ -218,7 +218,7 @@ check_embedded_art(const char * path, const char * image_data, int image_size)
}
last_hash = hash;
imsrc = image_new_from_jpeg(NULL, 0, image_data, image_size);
imsrc = image_new_from_jpeg(NULL, 0, image_data, image_size, 1);
if( !imsrc )
{
last_success = 0;
@ -286,7 +286,7 @@ check_for_album_file(char * dir, const char * path)
if( art_cache_exists(file, &art_file) )
goto existing_file;
free(art_file);
imsrc = image_new_from_jpeg(file, 1, NULL, 0);
imsrc = image_new_from_jpeg(file, 1, NULL, 0, 1);
if( imsrc )
goto found_file;
}
@ -298,7 +298,7 @@ check_for_album_file(char * dir, const char * path)
if( art_cache_exists(file, &art_file) )
goto existing_file;
free(art_file);
imsrc = image_new_from_jpeg(file, 1, NULL, 0);
imsrc = image_new_from_jpeg(file, 1, NULL, 0, 1);
if( imsrc )
goto found_file;
}
@ -316,7 +316,7 @@ existing_file:
return art_file;
}
free(art_file);
imsrc = image_new_from_jpeg(file, 1, NULL, 0);
imsrc = image_new_from_jpeg(file, 1, NULL, 0, 1);
if( !imsrc )
continue;
found_file:

View File

@ -393,7 +393,7 @@ image_new(int32_t width, int32_t height)
}
image *
image_new_from_jpeg(const char * path, int is_file, const char * buf, int size)
image_new_from_jpeg(const char * path, int is_file, const char * buf, int size, int scale)
{
image *vimage;
FILE *file = NULL;
@ -427,6 +427,7 @@ image_new_from_jpeg(const char * path, int is_file, const char * buf, int size)
return NULL;
}
jpeg_read_header(&cinfo, TRUE);
cinfo.scale_denom = scale;
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);

View File

@ -27,7 +27,7 @@ int
image_get_jpeg_resolution(const char * path, int * width, int * height);
image *
image_new_from_jpeg(const char * path, int is_file, const char * ptr, int size);
image_new_from_jpeg(const char * path, int is_file, const char * ptr, int size, int scale);
image *
image_resize(image * src_image, int32_t width, int32_t height);

View File

@ -558,7 +558,7 @@ GetImageMetadata(const char * path, char * name)
/* We might need to verify that the thumbnail is 160x160 or smaller */
if( ed->size > 12000 )
{
imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size);
imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1);
if( imsrc )
{
if( (imsrc->width <= 160) && (imsrc->height <= 160) )

View File

@ -719,6 +719,7 @@ ProcessTiVoCommand(struct upnphttp * h, const char * orig_path)
{
strip_ext(anchorItem);
}
free(path);
if( command )
{
@ -741,9 +742,9 @@ ProcessTiVoCommand(struct upnphttp * h, const char * orig_path)
{
DPRINTF(E_DEBUG, L_GENERAL, "Unhandled command [%s]\n", command);
Send501(h);
return;
}
}
free(path);
CloseSocket_upnphttp(h);
}
#endif // TIVO_SUPPORT

View File

@ -1382,9 +1382,12 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
char *pixelshape=NULL;
sqlite_int64 id;
int rows=0, chunked=0, ret;
#ifdef __sparc__
ExifData *ed;
ExifLoader *l;
#endif
image *imsrc = NULL, *imdst = NULL;
int scale = 1;
id = strtoll(object, NULL, 10);
sprintf(str_buf, "SELECT PATH, RESOLUTION, THUMBNAIL from DETAILS where ID = '%lld'", id);
@ -1472,6 +1475,13 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
else
strcpy(dlna_pn, "LRG");
if( srcw>>3 >= dstw && srch>>3 >= dsth)
scale = 8;
else if( srcw>>2 >= dstw && srch>>2 >= dsth )
scale = 4;
else if( srcw>>1 >= dstw && srch>>1 >= dsth )
scale = 2;
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
snprintf(header, sizeof(header)-100, "HTTP/1.1 200 OK\r\n"
"Content-Type: image/jpeg\r\n"
@ -1492,11 +1502,8 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
}
/* Resizing from a thumbnail is much faster than from a large image */
#ifdef __sparc__
if( dstw <= 200 && dsth <= 150 && atoi(tn) )
#else
#ifdef __sparc__
if( dstw <= 160 && dsth <= 120 && atoi(tn) )
#endif
{
l = exif_loader_new();
exif_loader_write_file(l, file_path);
@ -1507,15 +1514,18 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
{
if( ed )
exif_data_unref(ed);
Send404(h);
DPRINTF(E_WARN, L_HTTP, "Unable to access image thumbnail!\n");
Send500(h);
goto resized_error;
}
imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size);
imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1);
exif_data_unref(ed);
}
else if( strcmp(h->HttpVer, "HTTP/1.0") == 0 )
else
#endif
if( strcmp(h->HttpVer, "HTTP/1.0") == 0 )
{
imsrc = image_new_from_jpeg(file_path, 1, NULL, 0);
imsrc = image_new_from_jpeg(file_path, 1, NULL, 0, scale);
}
else
{
@ -1527,7 +1537,8 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
{
if( !imsrc )
{
Send404(h);
DPRINTF(E_WARN, L_HTTP, "Unable to open image %s!\n", file_path);
Send500(h);
goto resized_error;
}
@ -1542,10 +1553,11 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
{
if( chunked )
{
imsrc = image_new_from_jpeg(file_path, 1, NULL, 0);
imsrc = image_new_from_jpeg(file_path, 1, NULL, 0, scale);
if( !imsrc )
{
Send404(h);
DPRINTF(E_WARN, L_HTTP, "Unable to open image %s!\n", file_path);
Send500(h);
goto resized_error;
}
imdst = image_resize(imsrc, dstw, dsth);