Skip to content

Commit

Permalink
Use libjpeg to do some scaling (issue #253).
Browse files Browse the repository at this point in the history
  • Loading branch information
joewing committed Nov 21, 2015
1 parent eefdb50 commit 917a139
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/icon.c
Expand Up @@ -307,7 +307,7 @@ IconNode *LoadNamedIcon(const char *name, char save, char preserveAspect)

/* Check for an absolute file name. */
if(name[0] == '/') {
ImageNode *image = LoadImage(name);
ImageNode *image = LoadImage(name, 0, 0);
if(image) {
icon = CreateIcon(image);
icon->preserveAspect = preserveAspect;
Expand Down Expand Up @@ -352,7 +352,7 @@ IconNode *LoadNamedIconHelper(const char *name, const char *path,
for(i = 0; i < EXTENSION_COUNT; i++) {
const unsigned len = strlen(ICON_EXTENSIONS[i]);
memcpy(&temp[pathLength + nameLength], ICON_EXTENSIONS[i], len + 1);
ImageNode *image = LoadImage(temp);
ImageNode *image = LoadImage(temp, 0, 0);
if(image) {
result = CreateIcon(image);
result->preserveAspect = preserveAspect;
Expand Down Expand Up @@ -491,7 +491,7 @@ ImageNode *GetBestImage(IconNode *icon, int rwidth, int rheight)

/* If we don't have an image loaded, load one. */
if(icon->images == NULL) {
return LoadImage(icon->name);
return LoadImage(icon->name, rwidth, rheight);
}

/* Find the best image to use.
Expand Down
35 changes: 26 additions & 9 deletions src/image.c
Expand Up @@ -36,11 +36,11 @@

#ifdef USE_CAIRO
#ifdef USE_RSVG
static ImageNode *LoadSVGImage(const char *fileName);
static ImageNode *LoadSVGImage(const char *fileName, int width, int height);
#endif
#endif
#ifdef USE_JPEG
static ImageNode *LoadJPEGImage(const char *fileName);
static ImageNode *LoadJPEGImage(const char *fileName, int width, int height);
#endif
#ifdef USE_PNG
static ImageNode *LoadPNGImage(const char *fileName);
Expand All @@ -63,7 +63,7 @@ static int FreeColors(Display *d, Colormap cmap, Pixel *pixels, int n,
#endif

/** Load an image from the specified file. */
ImageNode *LoadImage(const char *fileName)
ImageNode *LoadImage(const char *fileName, int width, int height)
{
unsigned nameLength;
ImageNode *result = NULL;
Expand Down Expand Up @@ -93,7 +93,7 @@ ImageNode *LoadImage(const char *fileName)
&& !StrCmpNoCase(&fileName[nameLength - 4], ".jpg"))
|| (nameLength >= 5
&& !StrCmpNoCase(&fileName[nameLength - 5], ".jpeg"))) {
result = LoadJPEGImage(fileName);
result = LoadJPEGImage(fileName, width, height);
if(result) {
return result;
}
Expand All @@ -105,7 +105,7 @@ ImageNode *LoadImage(const char *fileName)
#ifdef USE_RSVG
if(nameLength >= 4
&& !StrCmpNoCase(&fileName[nameLength - 4], ".svg")) {
result = LoadSVGImage(fileName);
result = LoadSVGImage(fileName, width, height);
if(result) {
return result;
}
Expand Down Expand Up @@ -311,9 +311,8 @@ static void JPEGErrorHandler(j_common_ptr cinfo) {
longjmp(es->jbuffer, 1);
}

ImageNode *LoadJPEGImage(const char *fileName)
ImageNode *LoadJPEGImage(const char *fileName, int width, int height)
{

static ImageNode *result;
static struct jpeg_decompress_struct cinfo;
static FILE *fd;
Expand All @@ -323,6 +322,7 @@ ImageNode *LoadJPEGImage(const char *fileName)
int rowStride;
int x;
int inIndex, outIndex;
int xscale, yscale;

/* Open the file. */
fd = fopen(fileName, "rb");
Expand Down Expand Up @@ -353,13 +353,30 @@ ImageNode *LoadJPEGImage(const char *fileName)
/* Check the header. */
jpeg_read_header(&cinfo, TRUE);

/* Pick an appropriate scale for the image.
* We scale the image by the scale value for the dimension with
* the smallest absolute change.
*/
jpeg_calc_output_dimensions(&cinfo);
if(width != 0 && height != 0) {
/* Scale using n/8 with n in [1..8]. */
int ratio;
if(abs(cinfo.output_width - width) < abs(cinfo.output_height - height)) {
ratio = (width << 4) / cinfo.output_width;
} else {
ratio = (height << 4) / cinfo.output_height;
}
cinfo.scale_num = Max(1, Min(8, (ratio >> 2)));
cinfo.scale_denom = 8;
}

/* Start decompression. */
jpeg_start_decompress(&cinfo);
rowStride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,
JPOOL_IMAGE, rowStride, 1);

result = CreateImage(cinfo.image_width, cinfo.image_height, 0);
result = CreateImage(cinfo.output_width, cinfo.output_height, 0);
result->data = Allocate(4 * result->width * result->height);

/* Read lines. */
Expand Down Expand Up @@ -398,7 +415,7 @@ ImageNode *LoadJPEGImage(const char *fileName)

#ifdef USE_CAIRO
#ifdef USE_RSVG
ImageNode *LoadSVGImage(const char *fileName)
ImageNode *LoadSVGImage(const char *fileName, int width, int height)
{

#if !GLIB_CHECK_VERSION(2, 35, 0)
Expand Down
4 changes: 3 additions & 1 deletion src/image.h
Expand Up @@ -26,9 +26,11 @@ typedef struct ImageNode {

/** Load an image from a file.
* @param fileName The file containing the image.
* @param width The preferred width.
* @param height The preferred height.
* @return A new image node (NULL if the image could not be loaded).
*/
ImageNode *LoadImage(const char *fileName);
ImageNode *LoadImage(const char *fileName, int width, int height);

/** Load an image from a Drawable.
* @param pmap The drawable.
Expand Down

0 comments on commit 917a139

Please sign in to comment.