* Optimize JPEG scaling by downscaling as much as possible during decompression.
This commit is contained in:
parent
20bb1db8a7
commit
c779eab4de
@ -218,7 +218,7 @@ check_embedded_art(const char * path, const char * image_data, int image_size)
|
|||||||
}
|
}
|
||||||
last_hash = hash;
|
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 )
|
if( !imsrc )
|
||||||
{
|
{
|
||||||
last_success = 0;
|
last_success = 0;
|
||||||
@ -286,7 +286,7 @@ check_for_album_file(char * dir, const char * path)
|
|||||||
if( art_cache_exists(file, &art_file) )
|
if( art_cache_exists(file, &art_file) )
|
||||||
goto existing_file;
|
goto existing_file;
|
||||||
free(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 )
|
if( imsrc )
|
||||||
goto found_file;
|
goto found_file;
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ check_for_album_file(char * dir, const char * path)
|
|||||||
if( art_cache_exists(file, &art_file) )
|
if( art_cache_exists(file, &art_file) )
|
||||||
goto existing_file;
|
goto existing_file;
|
||||||
free(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 )
|
if( imsrc )
|
||||||
goto found_file;
|
goto found_file;
|
||||||
}
|
}
|
||||||
@ -316,7 +316,7 @@ existing_file:
|
|||||||
return art_file;
|
return art_file;
|
||||||
}
|
}
|
||||||
free(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 )
|
if( !imsrc )
|
||||||
continue;
|
continue;
|
||||||
found_file:
|
found_file:
|
||||||
|
@ -393,7 +393,7 @@ image_new(int32_t width, int32_t height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
image *
|
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;
|
image *vimage;
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
@ -427,6 +427,7 @@ image_new_from_jpeg(const char * path, int is_file, const char * buf, int size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
cinfo.scale_denom = scale;
|
||||||
cinfo.do_fancy_upsampling = FALSE;
|
cinfo.do_fancy_upsampling = FALSE;
|
||||||
cinfo.do_block_smoothing = FALSE;
|
cinfo.do_block_smoothing = FALSE;
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
|
@ -27,7 +27,7 @@ int
|
|||||||
image_get_jpeg_resolution(const char * path, int * width, int * height);
|
image_get_jpeg_resolution(const char * path, int * width, int * height);
|
||||||
|
|
||||||
image *
|
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 *
|
||||||
image_resize(image * src_image, int32_t width, int32_t height);
|
image_resize(image * src_image, int32_t width, int32_t height);
|
||||||
|
@ -558,7 +558,7 @@ GetImageMetadata(const char * path, char * name)
|
|||||||
/* We might need to verify that the thumbnail is 160x160 or smaller */
|
/* We might need to verify that the thumbnail is 160x160 or smaller */
|
||||||
if( ed->size > 12000 )
|
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 )
|
||||||
{
|
{
|
||||||
if( (imsrc->width <= 160) && (imsrc->height <= 160) )
|
if( (imsrc->width <= 160) && (imsrc->height <= 160) )
|
||||||
|
@ -719,6 +719,7 @@ ProcessTiVoCommand(struct upnphttp * h, const char * orig_path)
|
|||||||
{
|
{
|
||||||
strip_ext(anchorItem);
|
strip_ext(anchorItem);
|
||||||
}
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
if( command )
|
if( command )
|
||||||
{
|
{
|
||||||
@ -741,9 +742,9 @@ ProcessTiVoCommand(struct upnphttp * h, const char * orig_path)
|
|||||||
{
|
{
|
||||||
DPRINTF(E_DEBUG, L_GENERAL, "Unhandled command [%s]\n", command);
|
DPRINTF(E_DEBUG, L_GENERAL, "Unhandled command [%s]\n", command);
|
||||||
Send501(h);
|
Send501(h);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(path);
|
|
||||||
CloseSocket_upnphttp(h);
|
CloseSocket_upnphttp(h);
|
||||||
}
|
}
|
||||||
#endif // TIVO_SUPPORT
|
#endif // TIVO_SUPPORT
|
||||||
|
34
upnphttp.c
34
upnphttp.c
@ -1382,9 +1382,12 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
|||||||
char *pixelshape=NULL;
|
char *pixelshape=NULL;
|
||||||
sqlite_int64 id;
|
sqlite_int64 id;
|
||||||
int rows=0, chunked=0, ret;
|
int rows=0, chunked=0, ret;
|
||||||
|
#ifdef __sparc__
|
||||||
ExifData *ed;
|
ExifData *ed;
|
||||||
ExifLoader *l;
|
ExifLoader *l;
|
||||||
|
#endif
|
||||||
image *imsrc = NULL, *imdst = NULL;
|
image *imsrc = NULL, *imdst = NULL;
|
||||||
|
int scale = 1;
|
||||||
|
|
||||||
id = strtoll(object, NULL, 10);
|
id = strtoll(object, NULL, 10);
|
||||||
sprintf(str_buf, "SELECT PATH, RESOLUTION, THUMBNAIL from DETAILS where ID = '%lld'", id);
|
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
|
else
|
||||||
strcpy(dlna_pn, "LRG");
|
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));
|
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"
|
snprintf(header, sizeof(header)-100, "HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: image/jpeg\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 */
|
/* Resizing from a thumbnail is much faster than from a large image */
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
if( dstw <= 200 && dsth <= 150 && atoi(tn) )
|
|
||||||
#else
|
|
||||||
if( dstw <= 160 && dsth <= 120 && atoi(tn) )
|
if( dstw <= 160 && dsth <= 120 && atoi(tn) )
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
l = exif_loader_new();
|
l = exif_loader_new();
|
||||||
exif_loader_write_file(l, file_path);
|
exif_loader_write_file(l, file_path);
|
||||||
@ -1507,15 +1514,18 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
|||||||
{
|
{
|
||||||
if( ed )
|
if( ed )
|
||||||
exif_data_unref(ed);
|
exif_data_unref(ed);
|
||||||
Send404(h);
|
DPRINTF(E_WARN, L_HTTP, "Unable to access image thumbnail!\n");
|
||||||
|
Send500(h);
|
||||||
goto resized_error;
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -1527,7 +1537,8 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
|||||||
{
|
{
|
||||||
if( !imsrc )
|
if( !imsrc )
|
||||||
{
|
{
|
||||||
Send404(h);
|
DPRINTF(E_WARN, L_HTTP, "Unable to open image %s!\n", file_path);
|
||||||
|
Send500(h);
|
||||||
goto resized_error;
|
goto resized_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1542,10 +1553,11 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
|||||||
{
|
{
|
||||||
if( chunked )
|
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 )
|
if( !imsrc )
|
||||||
{
|
{
|
||||||
Send404(h);
|
DPRINTF(E_WARN, L_HTTP, "Unable to open image %s!\n", file_path);
|
||||||
|
Send500(h);
|
||||||
goto resized_error;
|
goto resized_error;
|
||||||
}
|
}
|
||||||
imdst = image_resize(imsrc, dstw, dsth);
|
imdst = image_resize(imsrc, dstw, dsth);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user