[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
aCaB
acab at clamav.net
Sun Apr 4 01:10:36 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 7b3ff9e9ae074a640791740706d9adefa6f6aa5d
Author: aCaB <acab at clamav.net>
Date: Mon Dec 7 01:50:49 2009 +0100
scale
diff --git a/libclamav/pe_icons.c b/libclamav/pe_icons.c
index 1bd4cec..fd86efa 100644
--- a/libclamav/pe_icons.c
+++ b/libclamav/pe_icons.c
@@ -69,7 +69,7 @@ struct GICONS {
static int groupicon_cb(void *ptr, uint32_t type, uint32_t name, uint32_t lang, uint32_t rva) {
struct GICONS *gicons = ptr;
type = type; lang = lang;
- cli_warnmsg("got group %u\n", name);
+ cli_dbgmsg("got group %u\n", name);
if(!gicons->cnt || gicons->lastg == name) {
gicons->rvas[gicons->cnt] = rva;
gicons->cnt++;
@@ -88,7 +88,7 @@ struct ICONS {
static int icon_cb(void *ptr, uint32_t type, uint32_t name, uint32_t lang, uint32_t rva) {
struct ICONS *icons = ptr;
type = type; lang = lang;
- cli_warnmsg("got icon %u\n", name);
+ cli_dbgmsg("got icon %u\n", name);
if(icons->cnt > 100)
return 1;
icons->rvas[icons->cnt] = rva;
@@ -134,7 +134,7 @@ int scanicon(uint32_t resdir_rva, cli_ctx *ctx, struct cli_exe_section *exe_sect
while(icnt && gsz >= 14) {
dir = (struct icondir *)grp;
- cli_warnmsg("Icongrp @%x - %ux%ux%u - (id=%x, rsvd=%u, planes=%u, palcnt=%u, sz=%x)\n", gicons.rvas[curicon], dir->w, dir->h, dir->depth, dir->id, dir->planes, dir->palcnt, dir->rsvd, dir->sz);
+ cli_dbgmsg("Icongrp @%x - %ux%ux%u - (id=%x, rsvd=%u, planes=%u, palcnt=%u, sz=%x)\n", gicons.rvas[curicon], dir->w, dir->h, dir->depth, dir->id, dir->planes, dir->palcnt, dir->rsvd, dir->sz);
findres(3, dir->id, resdir_rva, ctx, exe_sections, nsections, hdr_size, icon_cb, &icons);
grp += 14;
gsz -= 14;
@@ -671,40 +671,40 @@ static uint32_t labdiff2(unsigned int b) {
return ((uint32_t)(sqrt(ld/1024.0)))>>17;
}
-/* static void makebmp(int image, char *step, int w, int h, void *data) { */
-/* unsigned int tmp, y; */
-/* char fname[256]; */
-/* FILE *f; */
-
-/* if(!reallysave) return; */
-/* if(image >= 0) */
-/* snprintf(fname, sizeof(fname), "out-%02d-%s.bmp", image, step); */
-/* else */
-/* snprintf(fname, sizeof(fname), "out-ref-%s.bmp", step); */
-/* f = fopen(fname, "w"); */
-/* fwrite("BM", 2, 1, f); */
-/* tmp = 0x28 + 0xe + w * h * 4; */
-/* fwrite(&tmp, 4, 1, f); */
-/* fwrite("aCaB\x36\x00\x00\x00\x28\x00\x00\x00", 12, 1, f); */
-/* fwrite(&w, 4, 1, f); */
-/* fwrite(&h, 4, 1, f); */
-/* tmp = (32 << 16) | 1; */
-/* fwrite(&tmp, 4, 1, f); */
-/* tmp = 0; */
-/* fwrite(&tmp, 4, 1, f); */
-/* tmp = w * h * 4; */
-/* fwrite(&tmp, 4, 1, f); */
-/* fwrite("\1\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0", 16, 1, f); */
-/* for(y=h-1; y<h; y--) */
-/* fwrite(&((unsigned int *)data)[y*w], w, 4, f); */
-/* fclose(f); */
-/* spam("%s saved\n", fname); */
-/* } */
-
-#define makebmp(a,b,c,d,e)
-
-static unsigned int matchpoint(unsigned int w, unsigned int h, unsigned int *x1, unsigned int *y1, unsigned int *avg1, unsigned int *x2, unsigned int *y2, unsigned int *avg2, unsigned int max) {
- unsigned int i, j, best, match = 0, ksize = w / 4;
+#define DUMPBMP
+#ifdef DUMPBMP
+int nimage = 0;
+static void makebmp(char *step, int w, int h, void *data) {
+ unsigned int tmp, y;
+ char fname[256];
+ FILE *f;
+
+ snprintf(fname, sizeof(fname), "out-%02d-%s.bmp", nimage++, step);
+ f = fopen(fname, "w");
+ fwrite("BM", 2, 1, f);
+ tmp = 0x28 + 0xe + w * h * 4;
+ fwrite(&tmp, 4, 1, f);
+ fwrite("aCaB\x36\x00\x00\x00\x28\x00\x00\x00", 12, 1, f);
+ fwrite(&w, 4, 1, f);
+ fwrite(&h, 4, 1, f);
+ tmp = (32 << 16) | 1;
+ fwrite(&tmp, 4, 1, f);
+ tmp = 0;
+ fwrite(&tmp, 4, 1, f);
+ tmp = w * h * 4;
+ fwrite(&tmp, 4, 1, f);
+ fwrite("\1\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0", 16, 1, f);
+ for(y=h-1; y<h; y--)
+ fwrite(&((unsigned int *)data)[y*w], w, 4, f);
+ fclose(f);
+ cli_dbgmsg("%s saved\n", fname);
+}
+#else
+#define makebmp(a,b,c,d)
+#endif
+
+static unsigned int matchpoint(unsigned int side, unsigned int *x1, unsigned int *y1, unsigned int *avg1, const unsigned int *x2, const unsigned int *y2, const unsigned int *avg2, unsigned int max) {
+ unsigned int i, j, best, match = 0, ksize = side / 4;
for(i=0; i<3; i++) {
best = 0;
@@ -713,7 +713,7 @@ static unsigned int matchpoint(unsigned int w, unsigned int h, unsigned int *x1,
int diffx = (int)x1[i] - (int)x2[j];
int diffy = ((int)y1[i] - (int)y2[j]);
unsigned int diff = sqrt(diffx*diffx + diffy*diffy);
- if(diff > ksize * 3 / 4 || abs((int)avg1[i]-(int)avg2[j]) > max / 5)
+ if(diff > ksize * 3 / 4 || (unsigned int)abs((int)avg1[i]-(int)avg2[j]) > max / 5)
continue;
diff = 100 - diff * 60 / (ksize * 3 / 4);
@@ -740,11 +740,11 @@ static void hsv(unsigned int c, unsigned int *r, unsigned int *g, unsigned int *
*s = 255 * (*delta) / max;
}
-static int getmetrics(unsigned int width, unsigned int height, unsigned int *imagedata, struct icomtr *res) {
+static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr *res) {
unsigned int x, y, xk, yk, i, j, *tmp;
- unsigned int ksize = width / 4;
+ unsigned int ksize = side / 4;
- if(!(tmp = cli_malloc(width*height*4*2)))
+ if(!(tmp = cli_malloc(side*side*4*2)))
return CL_EMEM;
memset(res, 0, sizeof(*res));
@@ -755,8 +755,8 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
/* compute colored, gray, bright and dark areas, color presence */
- for(y=0; y<=height - ksize; y++) {
- for(x=0; x<=width - ksize; x++) {
+ for(y=0; y<=side - ksize; y++) {
+ for(x=0; x<=side - ksize; x++) {
unsigned int colsum = 0, lightsum = 0;
unsigned int r, g, b, s, v, delta;
@@ -764,7 +764,7 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
/* Here we handle the 1st window which is fully calculated */
for(yk=0; yk<ksize; yk++) {
for(xk=0; xk<ksize; xk++) {
- hsv(imagedata[yk * width + xk], &r, &g, &b, &s, &v, &delta);
+ hsv(imagedata[yk * side + xk], &r, &g, &b, &s, &v, &delta);
colsum += (unsigned int)sqrt(s*s*v);
lightsum += v;
@@ -779,15 +779,15 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
}
} else if(x) { /* Here we incrementally calculate rows and columns
code is split as gcc produces faster code this way */
- colsum = tmp[y*width+x-1];
- lightsum = tmp[height*width + y*width+x-1];
+ colsum = tmp[y*side+x-1];
+ lightsum = tmp[side*side + y*side+x-1];
for(yk=0; yk<ksize; yk++) {
/* remove previous column */
- hsv(imagedata[(y+yk) * width + x-1], &r, &g, &b, &s, &v, &delta);
+ hsv(imagedata[(y+yk) * side + x-1], &r, &g, &b, &s, &v, &delta);
colsum -= (unsigned int)sqrt(s*s*v);
lightsum -= v;
/* add next column */
- hsv(imagedata[(y+yk) * width + x+ksize-1], &r, &g, &b, &s, &v, &delta);
+ hsv(imagedata[(y+yk) * side + x+ksize-1], &r, &g, &b, &s, &v, &delta);
colsum += (unsigned int)sqrt(s*s*v);
lightsum += v;
@@ -800,16 +800,16 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
}
}
} else {
- colsum = tmp[(y-1)*width];
- lightsum = tmp[height*width + (y-1)*width];
+ colsum = tmp[(y-1)*side];
+ lightsum = tmp[side*side + (y-1)*side];
for(xk=0; xk<ksize; xk++) {
/* remove previous row */
- hsv(imagedata[(y-1) * width + xk], &r, &g, &b, &s, &v, &delta);
+ hsv(imagedata[(y-1) * side + xk], &r, &g, &b, &s, &v, &delta);
colsum -= (unsigned int)sqrt(s*s*v);
lightsum -= v;
/* add next row */
- hsv(imagedata[(y+ksize-1) * width + xk], &r, &g, &b, &s, &v, &delta);
+ hsv(imagedata[(y+ksize-1) * side + xk], &r, &g, &b, &s, &v, &delta);
colsum += (unsigned int)sqrt(s*s*v);
lightsum += v;
@@ -822,17 +822,17 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
}
}
}
- tmp[y*width+x] = colsum;
- tmp[height*width + y*width+x] = lightsum;
+ tmp[y*side+x] = colsum;
+ tmp[side*side + y*side+x] = lightsum;
}
}
/* extract top 3 non overlapping areas for: colored, gray, bright and dark areas, color presence */
for(i=0; i<3; i++) {
- for(y=0; y<height - ksize; y++) {
- for(x=0; x<width-1 - ksize; x++) {
- unsigned int colsum = tmp[y*width+x], lightsum = tmp[height*width + y*width+x];
+ for(y=0; y<side - ksize; y++) {
+ for(x=0; x<side-1 - ksize; x++) {
+ unsigned int colsum = tmp[y*side+x], lightsum = tmp[side*side + y*side+x];
if(colsum > res->color_avg[i]) {
for(j=0; j<i; j++) {
@@ -894,8 +894,7 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
res->rsum /= res->ccount;
res->gsum /= res->ccount;
res->bsum /= res->ccount;
- cli_errmsg("res count = %u, width * height = %u\n", res->ccount, width * height);
- res->ccount = res->ccount * 100 / width / height;
+ res->ccount = res->ccount * 100 / side / side;
}
cli_dbgmsg("color areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->color_avg[0], res->color_x[0], res->color_y[0], res->color_avg[1], res->color_x[1], res->color_y[1], res->color_avg[2], res->color_x[2], res->color_y[2]);
@@ -909,7 +908,7 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
/* Sobel 1 - gradients */
i = 0;
#ifdef USE_FLOATS
- double *sobel = cli_malloc(width * height * sizeof(double));
+ double *sobel = cli_malloc(side * side * sizeof(double));
if(!sobel) {
free(tmp);
return CL_EMEM;
@@ -917,13 +916,13 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
#else
unsigned int *sobel = imagedata;
#endif
- for(y=0; y<height; y++) {
- for(x=0; x<width; x++) {
- sobel[y * width + x] = LABDIFF(imagedata[y * width + x]);
+ for(y=0; y<side; y++) {
+ for(x=0; x<side; x++) {
+ sobel[y * side + x] = LABDIFF(imagedata[y * side + x]);
}
}
- for(y=1; y<height-1; y++) {
- for(x=1; x<width-1; x++) {
+ for(y=1; y<side-1; y++) {
+ for(x=1; x<side-1; x++) {
unsigned int sob;
#ifdef USE_FLOATS
double gx, gy;
@@ -932,118 +931,118 @@ static int getmetrics(unsigned int width, unsigned int height, unsigned int *ima
#endif
/* X matrix */
- gx = sobel[(y-1) * width + (x-1)];
- gx += sobel[(y+0) * width + (x-1)] * 2;
- gx += sobel[(y+1) * width + (x-1)];
- gx -= sobel[(y-1) * width + (x+1)];
- gx -= sobel[(y+0) * width + (x+1)] * 2;
- gx -= sobel[(y+1) * width + (x+1)];
+ gx = sobel[(y-1) * side + (x-1)];
+ gx += sobel[(y+0) * side + (x-1)] * 2;
+ gx += sobel[(y+1) * side + (x-1)];
+ gx -= sobel[(y-1) * side + (x+1)];
+ gx -= sobel[(y+0) * side + (x+1)] * 2;
+ gx -= sobel[(y+1) * side + (x+1)];
/* Y matrix */
- gy = sobel[(y-1) * width + (x-1)];
- gy += sobel[(y-1) * width + (x+0)] * 2;
- gy += sobel[(y-1) * width + (x+1)];
- gy -= sobel[(y+1) * width + (x-1)];
- gy -= sobel[(y+1) * width + (x+0)] * 2;
- gy -= sobel[(y+1) * width + (x+1)];
+ gy = sobel[(y-1) * side + (x-1)];
+ gy += sobel[(y-1) * side + (x+0)] * 2;
+ gy += sobel[(y-1) * side + (x+1)];
+ gy -= sobel[(y+1) * side + (x-1)];
+ gy -= sobel[(y+1) * side + (x+0)] * 2;
+ gy -= sobel[(y+1) * side + (x+1)];
sob = (int)sqrt(gx*gx + gy*gy);
- tmp[y * width + x] = sob;
+ tmp[y * side + x] = sob;
if(sob > i) i = sob;
}
}
/* Sobel 2 - norm to max */
if(i) {
- for(y=1; y<height-1; y++) {
- for(x=1; x<width-1; x++) {
- unsigned int c = tmp[y * width + x];
+ for(y=1; y<side-1; y++) {
+ for(x=1; x<side-1; x++) {
+ unsigned int c = tmp[y * side + x];
c = c * 255 / i;
- imagedata[y * width + x] = 0xff000000 | c | (c<<8) | (c<<16);
+ imagedata[y * side + x] = 0xff000000 | c | (c<<8) | (c<<16);
}
}
}
/* black borders */
- for(x=0; x<width; x++) {
+ for(x=0; x<side; x++) {
imagedata[x] = 0xff000000;
- imagedata[(width-1) * width + x] = 0xff000000;
+ imagedata[(side-1) * side + x] = 0xff000000;
}
- for(y=0; y<height; y++) {
- imagedata[y * width] = 0xff000000;
- imagedata[y * width + width - 1] = 0xff000000;
+ for(y=0; y<side; y++) {
+ imagedata[y * side] = 0xff000000;
+ imagedata[y * side + side - 1] = 0xff000000;
}
- makebmp(nimage, "3-edge", width, height, imagedata);
+ makebmp("3-edge", side, side, imagedata);
/* gaussian blur */
- for(y=1; y<height-1; y++) {
- for(x=1; x<width-1; x++) {
+ for(y=1; y<side-1; y++) {
+ for(x=1; x<side-1; x++) {
unsigned int sum=0, tot=0;
int disp;
- for(disp=-MIN((int)x, gkernsz/2); disp<=MIN((int)(width-1 - x), gkernsz/2); disp++){
- unsigned int c = imagedata[y * width + x + disp] & 0xff;
+ for(disp=-MIN((int)x, gkernsz/2); disp<=MIN((int)(side-1 - x), gkernsz/2); disp++){
+ unsigned int c = imagedata[y * side + x + disp] & 0xff;
sum += c * gaussk[disp + gkernsz/2];
tot += gaussk[disp + gkernsz/2];
}
sum /= tot;
- imagedata[y * width + x] &= 0xff;
- imagedata[y * width + x] |= sum<<8;
+ imagedata[y * side + x] &= 0xff;
+ imagedata[y * side + x] |= sum<<8;
}
}
i=0;
- for(y=1; y<height-1; y++) {
- for(x=1; x<width-1; x++) {
+ for(y=1; y<side-1; y++) {
+ for(x=1; x<side-1; x++) {
unsigned int sum=0, tot=0;
int disp;
- for(disp=-MIN((int)y, gkernsz/2); disp<=MIN((int)(height-1 - y), gkernsz/2); disp++){
- unsigned int c = (imagedata[(y + disp) * width + x] >> 8) & 0xff;
+ for(disp=-MIN((int)y, gkernsz/2); disp<=MIN((int)(side-1 - y), gkernsz/2); disp++){
+ unsigned int c = (imagedata[(y + disp) * side + x] >> 8) & 0xff;
sum += c * gaussk[disp + gkernsz/2];
tot += gaussk[disp + gkernsz/2];
}
sum /= tot;
if(sum>i) i=sum;
- imagedata[y * width + x] = 0xff000000 | sum | (sum<<8) | (sum<<16);
+ imagedata[y * side + x] = 0xff000000 | sum | (sum<<8) | (sum<<16);
}
}
- makebmp(nimage, "4-gauss", width, height, imagedata);
+ makebmp("4-gauss", side, side, imagedata);
for(i=0; i<3; i++)
res->noedge_avg[i] = 0xffffffff;
/* calculate edges */
- for(y=0; y<=height - ksize; y++) {
- for(x=0; x<=width-1 - ksize; x++) {
+ for(y=0; y<=side - ksize; y++) {
+ for(x=0; x<=side-1 - ksize; x++) {
unsigned int sum = 0;
if(x==0 && y==0) { /* 1st windows */
for(yk=0; yk<ksize; yk++) {
for(xk=0; xk<ksize; xk++)
- sum += imagedata[(y + yk) * width + x + xk] & 0xff;
+ sum += imagedata[(y + yk) * side + x + xk] & 0xff;
}
} else if(x) { /* next column */
- sum = tmp[y*width + x - 1];
+ sum = tmp[y*side + x - 1];
for(yk=0; yk<ksize; yk++) {
- sum -= imagedata[(y + yk) * width + x - 1] & 0xff;
- sum += imagedata[(y + yk) * width + x + ksize - 1] & 0xff;
+ sum -= imagedata[(y + yk) * side + x - 1] & 0xff;
+ sum += imagedata[(y + yk) * side + x + ksize - 1] & 0xff;
}
} else { /* next row */
- sum = tmp[(y-1)*width];
+ sum = tmp[(y-1)*side];
for(xk=0; xk<ksize; xk++) {
- sum -= imagedata[(y - 1) * width + xk] & 0xff;
- sum += imagedata[(y + ksize - 1) * width + xk] & 0xff;
+ sum -= imagedata[(y - 1) * side + xk] & 0xff;
+ sum += imagedata[(y + ksize - 1) * side + xk] & 0xff;
}
}
- tmp[y*width + x] = sum;
+ tmp[y*side + x] = sum;
}
}
/* calculate best and worst 3 edged areas */
for(i=0; i<3; i++) {
- for(y=0; y<height - ksize; y++) {
- for(x=0; x<width-1 - ksize; x++) {
- unsigned int sum = tmp[y*width + x];
+ for(y=0; y<side - ksize; y++) {
+ for(x=0; x<side-1 - ksize; x++) {
+ unsigned int sum = tmp[y*side + x];
if(sum > res->edge_avg[i]) {
for(j=0; j<i; j++) {
@@ -1105,7 +1104,7 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
uint32_t *palette = NULL, *imagedata;
unsigned int scanlinesz, andlinesz;
unsigned int width, height, depth, x, y;
- unsigned int err;
+ unsigned int err, scalemode = 2;
fmap_t *map = *ctx->fmap;
uint32_t icoff = cli_rawaddr(rva, exe_sections, nsections, &err, map->len, hdr_size);
@@ -1132,18 +1131,34 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
width = EC32(bmphdr.w);
height = EC32(bmphdr.h) / 2;
- if(width > 256 || height > 256)
- return CL_SUCCESS;
depth = EC32(bmphdr.depth);
+ if(width > 256 || height > 256 || width < 16 || height < 16) {
+ cli_dbgmsg("Image too small or too big (%ux%u)\n", width, height);
+ return CL_SUCCESS;
+ }
+ if(width < height * 3 / 4 || height < width * 3 / 4) {
+ cli_dbgmsg("Image not square enough (%ux%u)\n", width, height);
+ return CL_SUCCESS;
+ }
+
+ /* scaling logic */
+ if(width == height) {
+ if(width == 16 && width == 24 && width == 32)
+ scalemode = 0;
+ else if(!(width % 32) || !(width % 24))
+ scalemode = 1;
+ else
+ scalemode = 2;
+ }
- cli_dbgmsg("Bitmap - %ux%ux%u\n", width, height, depth);
+ cli_dbgmsg("Bitmap - %ux%ux%u\n", width, height, depth);
/* check color depth and load palette */
switch(depth) {
default:
case 0:
/* PNG OR JPEG */
- cli_dbgmsg("Found PNG / JPG icon which is not yet sported\n");
+ cli_dbgmsg("PNG icons are not yet sported\n");
return CL_SUCCESS;
case 1:
case 4:
@@ -1226,7 +1241,7 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
}
if(palette) fmap_unneed_ptr(map, palette, (1<<depth) * sizeof(int));
- makebmp(icon, "0-noalpha", width, height, imagedata);
+ makebmp("0-noalpha", width, height, imagedata);
/* Set alpha on or off based on the mask */
if(depth & 0x1f) {
@@ -1244,7 +1259,7 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
}
}
}
- makebmp(icon, "1-alpha-mask", width, height, imagedata);
+ makebmp("1-alpha-mask", width, height, imagedata);
/* Blend alpha */
for(y=0; y<height; y++) {
@@ -1262,58 +1277,68 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
}
}
- /* Scale icon if too big */
- while(width > 32) {
- for(y=0; y<height; y+=2) {
- for(x=0; x<width; x+=2) {
- /* Fast 50% scaler with linear gamma */
- /* unsigned int c1 = imagedata[y * width + x], c2 =imagedata[y * width + x + 1], c3 = imagedata[(y+1) * width + x], c4 = imagedata[(y+1) * width + x + 1]; */
- /* c1 = (((c1 ^ c2) & 0xfefefefe)>>1) + (c1 & c2); */
- /* c2 = (((c3 ^ c4) & 0xfefefefe)>>1) + (c3 & c4); */
- /* imagedata[y/2 * width/2 + x/2] = (((c1 ^ c2) & 0xfefefefe)>>1) + (c1 & c2); */
-
- unsigned int sum_r, sum_g, sum_b;
- unsigned int c = imagedata[y * width + x];
- sum_r = scale[(c >> 16) & 0xff];
- sum_g = scale[(c >> 8) & 0xff];
- sum_b = scale[c & 0xff];
-
- c = imagedata[y * width + x + 1];
- sum_r += scale[(c >> 16) & 0xff];
- sum_g += scale[(c >> 8) & 0xff];
- sum_b += scale[c & 0xff];
-
- c = imagedata[(y+1) * width + x];
- sum_r += scale[(c >> 16) & 0xff];
- sum_g += scale[(c >> 8) & 0xff];
- sum_b += scale[c & 0xff];
-
- c = imagedata[(y+1) * width + x + 1];
- sum_r += scale[(c >> 16) & 0xff];
- sum_g += scale[(c >> 8) & 0xff];
- sum_b += scale[c & 0xff];
-
- sum_r = round(pow((double)sum_r / 4.0f, 1.0f / 2.2f));
- sum_g = round(pow((double)sum_g / 4.0f, 1.0f / 2.2f));
- sum_b = round(pow((double)sum_b / 4.0f, 1.0f / 2.2f));
-
- imagedata[y/2 * width/2 + x/2] = (((unsigned int)sum_r) << 16) | (((unsigned int)sum_g) << 8) | ((unsigned int)sum_b) | 0xff000000;
+
+ switch (scalemode) {
+ case 0:
+ break;
+ case 1:
+ /* Fast 50% scaler with linear gamma */
+ while(width > 32) {
+ for(y=0; y<height; y+=2) {
+ for(x=0; x<width; x+=2) {
+ unsigned int c1 = imagedata[y * width + x], c2 =imagedata[y * width + x + 1], c3 = imagedata[(y+1) * width + x], c4 = imagedata[(y+1) * width + x + 1];
+ c1 = (((c1 ^ c2) & 0xfefefefe)>>1) + (c1 & c2);
+ c2 = (((c3 ^ c4) & 0xfefefefe)>>1) + (c3 & c4);
+ imagedata[y/2 * width/2 + x/2] = (((c1 ^ c2) & 0xfefefefe)>>1) + (c1 & c2);
+ }
+ }
+ width /= 2;
+ height /= 2;
+ cli_dbgmsg("Fast scaling to %ux%u\n", width, height);
+ }
+ break;
+ case 2:
+ /* Slow up/down scale */
+ {
+ double scalex, scaley;
+ unsigned int newsize;
+ uint32_t *newdata;
+
+ if(abs((int)width - 32) + abs((int)height - 32) < abs((int)width - 24) + abs((int)height - 24))
+ newsize = 32;
+ else if(abs((int)width - 24) + abs((int)height - 24) < abs((int)width - 16) + abs((int)height - 16))
+ newsize = 24;
+ else
+ newsize = 16;
+ scalex = (double)width / newsize;
+ scaley = (double)height / newsize;
+ if(!(newdata = cli_malloc(newsize * newsize * sizeof(*newdata)))) {
+ return CL_SUCCESS;
+ }
+ memset(newdata, 0xaaccaabb, newsize * newsize * sizeof(*newdata));
+ cli_dbgmsg("Slow scaling to %ux%u (%f, %f)\n", newsize, newsize, scalex, scaley);
+ for(y = 0; y<newsize; y++) {
+ unsigned int oldy = round(y * scaley) * width;
+ for(x = 0; x<newsize; x++)
+ newdata[y*newsize + x] = imagedata[oldy + (unsigned int)round(x * scalex)];
}
+ free(imagedata);
+ height = newsize;
+ width = newsize;
+ imagedata = newdata;
}
- width /= 2;
- height /= 2;
}
- makebmp(icon, "2-alpha-blend", width, height, imagedata);
+ makebmp("2-alpha-blend", width, height, imagedata);
- getmetrics(width, height, imagedata, &metrics);
+ getmetrics(width, imagedata, &metrics);
{
- unsigned int color = matchpoint(width, height, metrics.color_x, metrics.color_y, metrics.color_avg, reference.color_x, reference.color_y, reference.color_avg, 4072);
- unsigned int gray = matchpoint(width, height, metrics.gray_x, metrics.gray_y, metrics.gray_avg, reference.gray_x, reference.gray_y, reference.gray_avg, 4072);
- unsigned int bright = matchpoint(width, height, metrics.bright_x, metrics.bright_y, metrics.bright_avg, reference.bright_x, reference.bright_y, reference.bright_avg, 255);
- unsigned int dark = matchpoint(width, height, metrics.dark_x, metrics.dark_y, metrics.dark_avg, reference.dark_x, reference.dark_y, reference.dark_avg, 255);
- unsigned int edge = matchpoint(width, height, metrics.edge_x, metrics.edge_y, metrics.edge_avg, reference.edge_x, reference.edge_y, reference.edge_avg, 255);
- unsigned int noedge = matchpoint(width, height, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, reference.noedge_x, reference.noedge_y, reference.noedge_avg, 255);
+ unsigned int color = matchpoint(width, metrics.color_x, metrics.color_y, metrics.color_avg, reference.color_x, reference.color_y, reference.color_avg, 4072);
+ unsigned int gray = matchpoint(width, metrics.gray_x, metrics.gray_y, metrics.gray_avg, reference.gray_x, reference.gray_y, reference.gray_avg, 4072);
+ unsigned int bright = matchpoint(width, metrics.bright_x, metrics.bright_y, metrics.bright_avg, reference.bright_x, reference.bright_y, reference.bright_avg, 255);
+ unsigned int dark = matchpoint(width, metrics.dark_x, metrics.dark_y, metrics.dark_avg, reference.dark_x, reference.dark_y, reference.dark_avg, 255);
+ unsigned int edge = matchpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, reference.edge_x, reference.edge_y, reference.edge_avg, 255);
+ unsigned int noedge = matchpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, reference.noedge_x, reference.noedge_y, reference.noedge_avg, 255);
unsigned int reds = abs((int)metrics.rsum - (int)reference.rsum) * 10;
reds = (reds < 100) * (100 - reds);
unsigned int greens = abs((int)metrics.gsum - (int)reference.gsum) * 10;
@@ -1331,13 +1356,13 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
used--;
}
- cli_warnmsg("color confidence: %u%%\n", color);
- cli_warnmsg("gray confidence: %u%%\n", gray);
- cli_warnmsg("bright confidence: %u%%\n", bright);
- cli_warnmsg("dark confidence: %u%%\n", dark);
- cli_warnmsg("edge confidence: %u%%\n", edge);
- cli_warnmsg("noedge confidence: %u%%\n", noedge);
- cli_warnmsg("spread confidence: red %u%%, green %u%%, blue %u%% - colors %u%%\n", reds, greens, blues, ccount);
+ cli_dbgmsg("color confidence: %u%%\n", color);
+ cli_dbgmsg("gray confidence: %u%%\n", gray);
+ cli_dbgmsg("bright confidence: %u%%\n", bright);
+ cli_dbgmsg("dark confidence: %u%%\n", dark);
+ cli_dbgmsg("edge confidence: %u%%\n", edge);
+ cli_dbgmsg("noedge confidence: %u%%\n", noedge);
+ cli_dbgmsg("spread confidence: red %u%%, green %u%%, blue %u%% - colors %u%%\n", reds, greens, blues, ccount);
confidence = (color + gray*2/3 + bright*2/3 + dark + edge + noedge*2/3 + colors) / used;
cli_warnmsg("confidence: %u\n", confidence);
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list