* Many changes for TiVo support. It actually [kinda] works. :)
This commit is contained in:
126
albumart.c
126
albumart.c
@ -61,130 +61,6 @@ check_res(int width, int height, char * dlna_pn)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Use our own boxfilter resizer, because gdCopyImageResampled is slow,
|
||||
* and gdCopyImageResized looks horrible when you downscale this much. */
|
||||
#define N_FRAC 8
|
||||
#define MASK_FRAC ((1 << N_FRAC) - 1)
|
||||
#define ROUND2(v) (((v) + (1 << (N_FRAC - 1))) >> N_FRAC)
|
||||
#define DIV(x, y) ( ((x) << (N_FRAC - 3)) / ((y) >> 3) )
|
||||
static void
|
||||
boxfilter_resize(gdImagePtr dst, gdImagePtr src,
|
||||
int dstX, int dstY, int srcX, int srcY,
|
||||
int dstW, int dstH, int srcW, int srcH)
|
||||
{
|
||||
int x, y;
|
||||
int sy1, sy2, sx1, sx2;
|
||||
|
||||
if(!dst->trueColor)
|
||||
{
|
||||
gdImageCopyResized(dst, src, dstX, dstY, srcX, srcY, dstW, dstH,
|
||||
srcW, srcH);
|
||||
return;
|
||||
}
|
||||
for(y = dstY; y < (dstY + dstH); y++)
|
||||
{
|
||||
sy1 = (((y - dstY) * srcH) << N_FRAC) / dstH;
|
||||
sy2 = (((y - dstY + 1) * srcH) << N_FRAC) / dstH;
|
||||
for(x = dstX; x < (dstX + dstW); x++)
|
||||
{
|
||||
int sx, sy;
|
||||
int spixels = 0;
|
||||
int red = 0, green = 0, blue = 0, alpha = 0;
|
||||
sx1 = (((x - dstX) * srcW) << N_FRAC) / dstW;
|
||||
sx2 = (((x - dstX + 1) * srcW) << N_FRAC) / dstW;
|
||||
sy = sy1;
|
||||
do {
|
||||
int yportion;
|
||||
if((sy >> N_FRAC) == (sy1 >> N_FRAC))
|
||||
{
|
||||
yportion = (1 << N_FRAC) - (sy & MASK_FRAC);
|
||||
if(yportion > sy2 - sy1)
|
||||
{
|
||||
yportion = sy2 - sy1;
|
||||
}
|
||||
sy = sy & ~MASK_FRAC;
|
||||
}
|
||||
else if(sy == (sy2 & ~MASK_FRAC))
|
||||
{
|
||||
yportion = sy2 & MASK_FRAC;
|
||||
}
|
||||
else
|
||||
{
|
||||
yportion = (1 << N_FRAC);
|
||||
}
|
||||
sx = sx1;
|
||||
do {
|
||||
int xportion;
|
||||
int pcontribution;
|
||||
int p;
|
||||
if((sx >> N_FRAC) == (sx1 >> N_FRAC))
|
||||
{
|
||||
xportion = (1 << N_FRAC) - (sx & MASK_FRAC);
|
||||
if(xportion > sx2 - sx1)
|
||||
{
|
||||
xportion = sx2 - sx1;
|
||||
}
|
||||
sx = sx & ~MASK_FRAC;
|
||||
}
|
||||
else if(sx == (sx2 & ~MASK_FRAC))
|
||||
{
|
||||
xportion = sx2 & MASK_FRAC;
|
||||
}
|
||||
else
|
||||
{
|
||||
xportion = (1 << N_FRAC);
|
||||
}
|
||||
|
||||
if(xportion && yportion)
|
||||
{
|
||||
pcontribution = (xportion * yportion) >> N_FRAC;
|
||||
p = gdImageGetTrueColorPixel(src, ROUND2(sx) + srcX, ROUND2(sy) + srcY);
|
||||
if(pcontribution == (1 << N_FRAC))
|
||||
{
|
||||
// optimization for down-scaler, which many pixel has pcontribution=1
|
||||
red += gdTrueColorGetRed(p) << N_FRAC;
|
||||
green += gdTrueColorGetGreen(p) << N_FRAC;
|
||||
blue += gdTrueColorGetBlue(p) << N_FRAC;
|
||||
alpha += gdTrueColorGetAlpha(p) << N_FRAC;
|
||||
spixels += (1 << N_FRAC);
|
||||
}
|
||||
else
|
||||
{
|
||||
red += gdTrueColorGetRed(p) * pcontribution;
|
||||
green += gdTrueColorGetGreen(p) * pcontribution;
|
||||
blue += gdTrueColorGetBlue(p) * pcontribution;
|
||||
alpha += gdTrueColorGetAlpha(p) * pcontribution;
|
||||
spixels += pcontribution;
|
||||
}
|
||||
}
|
||||
sx += (1 << N_FRAC);
|
||||
}
|
||||
while(sx < sx2);
|
||||
sy += (1 << N_FRAC);
|
||||
}
|
||||
while(sy < sy2);
|
||||
if(spixels != 0)
|
||||
{
|
||||
red = DIV(red, spixels);
|
||||
green = DIV(green, spixels);
|
||||
blue = DIV(blue, spixels);
|
||||
alpha = DIV(alpha, spixels);
|
||||
}
|
||||
/* Clamping to allow for rounding errors above */
|
||||
if(red > (255 << N_FRAC))
|
||||
red = (255 << N_FRAC);
|
||||
if(green > (255 << N_FRAC))
|
||||
green = (255 << N_FRAC);
|
||||
if(blue > (255 << N_FRAC))
|
||||
blue = (255 << N_FRAC);
|
||||
if(alpha > (gdAlphaMax << N_FRAC))
|
||||
alpha = (gdAlphaMax << N_FRAC);
|
||||
gdImageSetPixel(dst, x, y,
|
||||
gdTrueColorAlpha(ROUND2(red), ROUND2(green), ROUND2(blue), ROUND2(alpha)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
save_resized_album_art(void * ptr, const char * path, int srcw, int srch, int file, int size)
|
||||
{
|
||||
@ -230,7 +106,7 @@ save_resized_album_art(void * ptr, const char * path, int srcw, int srch, int fi
|
||||
fclose(dstfile);
|
||||
goto error;
|
||||
}
|
||||
#if 0 // Try our box filter resizer for now
|
||||
#if 0 // Try our box filter resizer instead
|
||||
#ifdef __sparc__
|
||||
gdImageCopyResized(imdst, imsrc, 0, 0, 0, 0, dstw, dsth, imsrc->sx, imsrc->sy);
|
||||
#else
|
||||
|
Reference in New Issue
Block a user