unsigned startcoeff;
};
-void hscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nw)
+void hscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nw)
{
struct pix_desc *pd = (struct pix_desc *)malloc(nw * sizeof(struct pix_desc));
int size_coeffs = 8;
int num_coeffs = 0;
int x, y, sx;
double sf = (double)w / (double)nw;
- double support = 3.0 * sf;
+ double support = (w > nw) ? (3.0 * sf) : (3.0 / sf);
/* calculate the filter */
for (x = 0; x < nw; ++x) {
pd[x].startcoeff = num_coeffs;
for (sx = start; sx <= end; ++sx) {
- double nd = sx/sf - x;
+ double nd = (w > nw) ? (sx/sf - x) : (sx - x*sf);
double f = lanczos_tap(nd);
if (num_coeffs == size_coeffs) {
size_coeffs <<= 1;
coeffs = (float *)realloc(coeffs, size_coeffs * sizeof(float));
}
-
+
coeffs[num_coeffs++] = f;
sum += f;
}
}
for (y = 0; y < h; ++y) {
- unsigned char *sptr = pix + y*w;
- float *dptr = npix + y*nw;
+ float *sptr = pix + y*w;
+ unsigned char *dptr = npix + y*nw;
for (x = 0; x < nw; ++x) {
float acc = 0.0;
float *cf = &coeffs[pd[x].startcoeff];
unsigned sx;
+ unsigned char ch;
for (sx = pd[x].start; sx <= pd[x].end; ++sx) {
acc += sptr[sx] * *cf++;
}
- *dptr++ = acc;
+
+ if (acc < 0.0)
+ ch = 0;
+ else if (acc > 255.0)
+ ch = 255;
+ else
+ ch = (unsigned char)acc;
+ *dptr++ = ch;
}
}
}
-void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh)
+void vscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nh)
{
struct pix_desc *pd = (struct pix_desc *)malloc(nh * sizeof(struct pix_desc));
int size_coeffs = 8;
int num_coeffs = 0;
int x, y, sy;
double sf = (double)h / (double)nh;
- double support = 3.0 * sf;
+ double support = (h > nh) ? (3.0 * sf) : (3.0 / sf);
/* calculate the filter */
for (y = 0; y < nh; ++y) {
pd[y].startcoeff = num_coeffs;
for (sy = start; sy <= end; ++sy) {
- double nd = sy/sf - y;
+ double nd = (h > nh) ? (sy/sf - y) : (sy - y*sf);
double f = lanczos_tap(nd);
if (num_coeffs == size_coeffs) {
size_coeffs <<= 1;
coeffs[pd[y].startcoeff + sy - start] /= sum;
}
}
+
#if CACHE_LINE_FACTOR > 1
for (x = 0; x < w; x += CACHE_LINE_FACTOR) {
- float *sptr = pix + x;
- unsigned char *dptr = npix + x;
+ unsigned char *sptr = pix + x;
+ float *dptr = npix + x;
for (y = 0; y < nh; ++y) {
int i;
float acc[CACHE_LINE_FACTOR];
acc[i] = 0.0;
float *cf = &coeffs[pd[y].startcoeff];
unsigned sy;
- unsigned char ch;
for (sy = pd[y].start; sy <= pd[y].end; ++sy) {
for (i = 0; i < CACHE_LINE_FACTOR; ++i) {
}
for (i = 0; i < CACHE_LINE_FACTOR; ++i) {
- if (acc[i] < 0.0)
- ch = 0;
- else if (acc[i] > 255.0)
- ch = 255;
- else
- ch = (unsigned char)acc[i];
- dptr[i] = ch;
+ dptr[i] = acc[i];
}
dptr += w;
}
}
-#endif
for (x = (x/CACHE_LINE_FACTOR)*CACHE_LINE_FACTOR; x < w; ++x) {
- float *sptr = pix + x;
- unsigned char *dptr = npix + x;
+#else
+ for (x = 0; x < w; ++x) {
+#endif
+ unsigned char *sptr = pix + x;
+ float *dptr = npix + x;
for (y = 0; y < nh; ++y) {
float acc = 0.0;
float *cf = &coeffs[pd[y].startcoeff];
unsigned sy;
- unsigned char ch;
for (sy = pd[y].start; sy <= pd[y].end; ++sy) {
acc += sptr[sy * w] * *cf++;
}
- if (acc < 0.0)
- ch = 0;
- else if (acc > 255.0)
- ch = 255;
- else
- ch = (unsigned char)acc;
-
- *dptr = ch;
+ *dptr = acc;
dptr += w;
}
}
{
unsigned w, h;
unsigned nw = 600, nh = 400;
+ //unsigned nw = 3504, nh = 2336;
char buf[256];
unsigned char *pix;
float *npix;
exit(1);
}
- hscale(pix, npix, w, h, nw);
- vscale(npix, npix2, nw, h, nh);
+ vscale(pix, npix, w, h, nh);
+ hscale(npix, npix2, w, nh, nw);
printf("P5\n# COMMENT: Made by qscale\n%u %u\n255\n", nw, nh);
{