Beispiel #1
0
static int64_t
_archive_filter_bytes(struct archive *_a, int n)
{
	struct archive_read_filter *f = get_filter(_a, n);
	return f == NULL ? -1 : f->position;
}
Beispiel #2
0
static int
_archive_filter_code(struct archive *_a, int n)
{
	struct archive_read_filter *f = get_filter(_a, n);
	return f == NULL ? -1 : f->code;
}
Beispiel #3
0
static const char *
_archive_filter_name(struct archive *_a, int n)
{
	struct archive_read_filter *f = get_filter(_a, n);
	return f == NULL ? NULL : f->name;
}
int main(int argc, char **argv) {
    struct jpeg_decompress_struct dinfo;
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    char *file1;   /* input filename */
    char *file2;   /* output filename */
    FILE *fh1;     /* input file handle */
    FILE *fh2;     /* output file handle */
    float *data;   /* partially-convolved rows in 4-tuples: r, g, b, sum */
    float **ptrs;  /* pointers into input buffer, one for each scanline */
    JSAMPLE *line; /* input/output buffer */
    float *fx,*fy; /* convolution kernel cache */
    int mode;      /* resize mode (see M_SET_SIZE, etc.) */
    int quality;   /* jpeg quality: 0 to 100 */
    int len;       /* length of one line in data */
    int w1, h1, z1; /* size of input image */
    int w2, h2;    /* size of output image */
    int w3, h3;    /* size of convolution kernel */
    int xo, yo;    /* number of cols/rows to side of center of kernel */
    int y1, n1;    /* first row and number of rows loaded into input buffer */
    int yc;        /* last row loaded from input file */
    int x2, y2;    /* current location in output image */
    float ox, oy;  /* offset of origin in input image */
    float sx, sy;  /* amount to scale horizontal and vertical */
    float xf, yf;  /* corresponding location in input image */
    float ax, ay;  /* constants needed for Lanczos kernel */
    float extra;   /* multiply kernel radius by this to get extra lobes */
    int kernel;    /* boolean: dump convolution kernel and abort? */
    int verbose;   /* boolean: verbose mode? */

    /* Temporary variables. */
    float *ptr1, *ptr2, *ptr3;
    JSAMPLE *ptr4;
    int x, y, i, j, k, c;
    float f, r, g, b, s, *accum;

    /* Print help message. */
    if (argc <= 1 || get_flag(argv, &argc, "-h", "--help")) {
        printf("\n");
        printf("USAGE\n");
        printf("    %s\n", USAGE);
        printf("\n");
        printf("OPTIONS\n");
        printf("    <w>x<h>             Width and height of output image, e.g., '200x200'.\n");
        printf("    <input.jpg>         Input image.  Must be 'normal' RGB color JPEG.\n");
        printf("    <output.jpg>        Output image.  Clobbers any existing file.\n");
        printf("\n");
        printf("    --set-size          Default mode: set to given size, ignoring aspect ratio.\n");
        printf("    --set-area          Keep aspect ratio, reducing/enlarging to area of given box.\n");
        printf("    --max-size          Keep aspect ratio, reducing to within given box.\n");
        printf("    --max-area          Keep aspect ratio, reducing to area of given box.\n");
        printf("    --min-size          Keep aspect ratio, enlarging to contain given box.\n");
        printf("    --min-area          Keep aspect ratio, enlarging to area of given box.\n");
        printf("    --crop              Reduce/enlarge, cropping to get correct ratio.\n");
        printf("\n");
        printf("    -q --quality <pct>  JPEG quality of output image; default depends on size.\n");
        printf("    -r --radius <n>     Radius of convolution kernel, > 0; default is 1.0.\n");
        printf("    -s --sharp <n>      Amount to sharpen output, >= 0; default is 0.2.\n");
        printf("\n");
        printf("    --flat              Average pixels within box of given radius.\n");
        printf("    --linear            Weight pixels within box linearly by closeness.\n");
        printf("    --hermite           Hermite cubic spline filter; similar to Gaussian.\n");
        printf("    --catrom [<M>]      Catmull-Rom cubic spline; default is M = 0.5 at R = 1.\n");
        printf("    --mitchell          Mitchell-Netravali filter (see Keys filter).\n");
        printf("    --keys [<B> <C>]    Keys family filters; default is B = C = 1/3 (Mitchell).\n");
        printf("    --lanczos [<N>]     Lanczos windowed sinc filter; default is N = 3 lobes.\n");
        printf("\n");
        printf("    -h --help           Print this message.\n");
        printf("    -v --verbose        Verbose / debug mode.\n");
        printf("    -k --kernel         Dump convolution kernel without processing image.\n");
        printf("\n");
        exit(1);
    }

    /* Get command line args. */
    get_size(argv, &argc, &w2, &h2);
    quality = get_value(argv, &argc, "-q", "--quality", default_quality(w2, h2));
    radius  = get_value(argv, &argc, "-r", "--radius", 1.0);
    sharp   = get_value(argv, &argc, "-s", "--sharp", 0.2);
    verbose = get_flag(argv, &argc, "-v", "--verbose");
    kernel  = get_flag(argv, &argc, "-k", "--kernel");

    /* Only allowed one mode flag. */
    mode = get_flag(argv, &argc, "--set-size", 0) ? M_SET_SIZE :
           get_flag(argv, &argc, "--max-size", 0) ? M_MAX_SIZE :
           get_flag(argv, &argc, "--min-size", 0) ? M_MIN_SIZE :
           get_flag(argv, &argc, "--set-area", 0) ? M_SET_AREA :
           get_flag(argv, &argc, "--max-area", 0) ? M_MAX_AREA :
           get_flag(argv, &argc, "--min-area", 0) ? M_MIN_AREA :
           get_flag(argv, &argc, "--crop",     0) ? M_CROP     : M_SET_SIZE;

    /* Each filter type takes different arguments. */
    if (get_filter(argv, &argc, "--flat", 0, 0, 0)) {
        filter = F_FLAT;
        extra  = 1.0;
    } else if (get_filter(argv, &argc, "--linear", 0, 0, 0)) {
        filter = F_LINEAR;
        extra  = 1.0;
    } else if (get_filter(argv, &argc, "--hermite", 0, 0, 0)) {
        filter = F_HERMITE;
        extra  = 1.0;
    } else if (get_filter(argv, &argc, "--catrom",   1, 1.0, 0.0)) {
        filter = F_CATROM;
        extra  = 2.0;
    } else if (get_filter(argv, &argc, "--mitchell", 0, 0.0, 0.0)) {
        filter = F_KEYS;
        extra  = 2.0;
        arg1   = 1.0 / 3.0;
        arg2   = 1.0 / 3.0;
    } else if (get_filter(argv, &argc, "--keys",     2, 1.0/3.0, 1.0/3.0)) {
        filter = F_KEYS;
        extra  = 2.0;
    } else if (get_filter(argv, &argc, "--lanczos",  1, 3.0, 0.0)) {
        filter = F_LANCZOS;
        extra  = arg1;
    } else {
        filter = F_LANCZOS;
        arg1   = 3.0;
        extra  = arg1;
    }

    /* Get files last because they complain if there are any flags left. */
    file1 = get_file(argv, &argc);
    file2 = get_file(argv, &argc);
    if (argc > 1) bad_usage("unexpected argument: %s", argv[1]);

    /* Create and initialize decompress object. */
    dinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&dinfo);
    if ((fh1 = fopen(file1, "rb")) == NULL) {
        fprintf(stderr, "can't open %s for reading\n", file1);
        exit(1);
    }
    jpeg_stdio_src(&dinfo, fh1);

    /* Get dimensions and format of input image. */
    jpeg_read_header(&dinfo, TRUE);
    jpeg_start_decompress(&dinfo);
    w1 = dinfo.output_width;
    h1 = dinfo.output_height;
    z1 = dinfo.output_components;

    /* Choose output size. */
    if (mode == M_SET_SIZE) {
        /* leave as is */
        sx = (double)w2 / w1;
        sy = (double)h2 / h1;
        ox = oy = 0.0;
    } else if (mode == M_MAX_SIZE) {
        if (w1 > w2 && h1 * w2 / w1 < h2) {
            sx = sy = (double)w2 / w1;
            h2 = sy * h1 + 0.5;
        } else if (h1 > h2) {
            sx = sy = (double)h2 / h1;
            w2 = sx * w1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_MIN_SIZE) {
        if (w1 < w2 && h1 * w2 / w1 > h2) {
            sx = sy = (double)w2 / w1;
            h2 = sy * h1 + 0.5;
        } else if (h1 < h2) {
            sx = sy = (double)h2 / h1;
            w2 = sx * w1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_SET_AREA) {
        sx = sy = sqrt(((double)w2) * h2 / w1 / h1);
        w2 = sx * w1 + 0.5;
        h2 = sy * h1 + 0.5;
        ox = oy = 0.0;
    } else if (mode == M_MAX_AREA) {
        if (w1 * h1 > w2 * h2) {
            sx = sy = sqrt(((double)w2) * h2 / w1 / h1);
            w2 = sx * w1 + 0.5;
            h2 = sy * h1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_MIN_AREA) {
        if (w1 * h1 < w2 * h2) {
            sx = sy = sqrt(((double)w2) * h2 / w1 / h1);
            w2 = sx * w1 + 0.5;
            h2 = sy * h1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_CROP) {
        sx = (double)w2 / w1;
        sy = (double)h2 / h1;
        sx = sy = sx > sy ? sx : sy;
        ox = ((double)w1 - (double)w2 / sx) * 0.5;
        oy = ((double)h1 - (double)h2 / sy) * 0.5;
    } else {
        fprintf(stderr, "invalid mode: %d!", mode);
        exit(1);
    }

    if (verbose) {
        fprintf(stderr, "input:   %dx%d (%d) %s\n", w1, h1, z1, file1);
        fprintf(stderr, "output:  %dx%d (%d) %s\n", w2, h2, z1, file2);
        if (sx > 1.0 && sy > 1.0)
            fprintf(stderr, "enlarge: %.2f %.2f\n", sx*1.0, sy*1.0);
        else
            fprintf(stderr, "reduce:  %.2f %.2f\n", 1.0/sx, 1.0/sy);
        fprintf(stderr, "origin:  %.2f %.2f\n", ox, oy);
        fprintf(stderr, "quality: %d\n", quality);
        fprintf(stderr, "radius:  %f\n", radius);
        fprintf(stderr, "sharp:   %f\n", sharp);
        if (filter == F_FLAT)    fprintf(stderr, "filter:  flat\n");
        if (filter == F_LINEAR)  fprintf(stderr, "filter:  bilinear\n");
        if (filter == F_HERMITE) fprintf(stderr, "filter:  hermite\n");
        if (filter == F_CATROM)  fprintf(stderr, "filter:  Catmull-Rom (M=%f)\n", arg1);
        if (filter == F_KEYS)    fprintf(stderr, "filter:  Keys-family (B=%f, C=%f)\n", arg1, arg2);
        if (filter == F_LANCZOS) fprintf(stderr, "filter:  Lanczos (N=%f)\n", arg1);
    }

    /* Calculate size of convolution kernel. */
    ax = sx < 1 ? radius / sx : radius;
    ay = sy < 1 ? radius / sy : radius;
    xo = (int)(ax * extra + 0.5);
    yo = (int)(ay * extra + 0.5);
    w3 = xo + xo + 1;
    h3 = yo + yo + 1;

    /* Pre-calculate coefficients for Keys-family filters. */
    if (filter == F_CATROM) {
        filter = F_KEYS;
        c1 = 2.0 - arg1;
        c2 = -3.0 + arg1;
        c3 = 0.0;
        c4 = 1.0;
        c5 = -arg1;
        c6 = 2.0 * arg1;
        c7 = -arg1;
        c8 = 0.0;
    } else if (filter == F_KEYS) {
        c1 = ( 12.0 + -9.0 * arg1 +  -6.0 * arg2) / 6.0;
        c2 = (-18.0 + 12.0 * arg1 +   6.0 * arg2) / 6.0;
        c3 = (  0.0 +  0.0 * arg1 +   0.0 * arg2) / 6.0;
        c4 = (  6.0 + -2.0 * arg1 +   0.0 * arg2) / 6.0;
        c5 = (  0.0 + -1.0 * arg1 +  -6.0 * arg2) / 6.0;
        c6 = (  0.0 +  3.0 * arg1 +  12.0 * arg2) / 6.0;
        c7 = (  0.0 + -3.0 * arg1 +  -6.0 * arg2) / 6.0;
        c8 = (  0.0 +  1.0 * arg1 +   0.0 * arg2) / 6.0;
    }

    if (verbose) {
        fprintf(stderr, "w1-h1:   %d %d\n", w1, h1);
        fprintf(stderr, "xo-yo:   %d %d\n", xo, yo);
        fprintf(stderr, "w3-h3:   %d %d\n", w3, h3);
        fprintf(stderr, "ax-ay:  %8.5f %8.5f\n", ax, ay);
        fprintf(stderr, "c1-4:   %8.5f %8.5f %8.5f %8.5f\n", c1, c2, c3, c4);
        fprintf(stderr, "c5-8:   %8.5f %8.5f %8.5f %8.5f\n", c5, c6, c7, c8);
    }

    /* Debug convolution kernel. */
    if (kernel) {
        f = -1;
        for (xf=0; xf<10.0; xf+=0.1) {
            s = calc_factor(xf);
            fprintf(stderr, "%5.2f %7.4f\n", xf, s);
            if (s == 0.0 && f == 0.0)
                break;
            f = s;
        }
        exit(0);
    }

    /* Allocate buffers. */
    len   = w2 * (z1 + 1);
    data  = (float*)malloc(h3 * len * sizeof(float));
    ptrs  = (float**)malloc(h3 * sizeof(float*));
    line  = (JSAMPLE*)malloc((w1 > w2 ? w1 : w2) * z1 * sizeof(JSAMPLE));
    fx    = (float*)malloc(w2 * w3 * sizeof(float));
    fy    = (float*)malloc(h2 * h3 * sizeof(float));
    accum = (float*)malloc(z1 * sizeof(float));

    /* Cache horizontal and vertical components of kernel. */
    for (x2=0, ptr3=fx; x2<w2; x2++) {
        xf = ((float)x2) / sx + ox;
        for (i=0, x=(int)xf-xo; i<w3; i++, x++) {
            *ptr3++ = calc_factor(fabs(xf-x) / ax);
        }
    }
    for (y2=0, ptr3=fy; y2<h2; y2++) {
        yf = ((float)y2) / sy + oy;
        for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
            *ptr3++ = calc_factor(fabs(yf-y) / ay);
        }
    }

    /* Create and initialize compress object. */
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    if ((fh2 = fopen(file2, "wb")) == NULL) {
        fprintf(stderr, "can't open %s for writing\n", file2);
        exit(1);
    }
    jpeg_stdio_dest(&cinfo, fh2);
    cinfo.image_width = w2;
    cinfo.image_height = h2;
    cinfo.input_components = z1;
    switch (z1) {
    case 1:
        cinfo.in_color_space = JCS_GRAYSCALE;
        break;
    case 3:
        cinfo.in_color_space = JCS_RGB;
        break;
    case 4:
        cinfo.in_color_space = JCS_CMYK;
        break;
    default:
        fprintf(stderr, "Not sure what colorspace to make output for input file with %d components.\n", z1);
        exit(1);
    }
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    /* Loop through output rows. */
    n1 = 0;  /* (num lines in buffer) */
    yc = -1; /* (last line loaded) */
    for (y2=0; y2<h2; y2++) {
        yf = ((float)y2) / sy + oy;

        /* Make sure we have the 'yo' rows above and below this row. */
        y = (int)yf - yo;
        if (y - y1 >= h3) n1 = 0;
        ptr1 = n1 ? ptrs[y - y1] : data;
        if (n1) n1 -= y - y1;
        for (i=0; i<h3; i++, y++) {

            /* Move already-loaded lines into place until run out. */
            ptrs[i] = ptr1;
            ptr1 += len;
            if (ptr1 >= data + len * h3) ptr1 = data;

            /* Need to load this line into next available slot. */
            /* It's okay to leave junk in lines outside input image. */
            if (n1-- <= 0 && y >= 0 && y < h1) {

                /* Read lines until get the one we want. */
                for (; yc<y; yc++) {
                    if (!jpeg_read_scanlines(&dinfo, &line, 1)) {
                        fprintf(stderr, "JPEG image corrupted at line %d.\n", yc);
                        exit(1);
                    }
                }

                /* Do horizontal part of convolution now.  Stores a partial
                /* result for each output column for this input row. */
/* ------------------------- start switch 1 on z1 ------------------------- */
                switch (z1) {
                case 1:
                    for (x2=0, ptr2=ptrs[i], ptr3=fx; x2<w2; x2++) {
                        xf = ((float)x2) / sx + ox;
                        r = s = 0;
                        for (j=0, x=(int)xf-xo; j<w3; j++, x++) {
                            f = *ptr3++;
                            if (x >= 0 && x < w1 && fabs(f) > 1e-8) {
                                ptr4 = line + x;
                                r += f * *ptr4++;
                                s += f;
                            }
                        }
                        if (fabs(s) > 1e-3) {
                            *ptr2++ = r;
                            *ptr2++ = s;
                        } else {
                            fprintf(stderr, "x factor near zero -- shouldn't happen!\n");
                            ptr4 = line + (int)xf;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = 1.0;
                        }
                    }
                    break;

                case 3:
                    for (x2=0, ptr2=ptrs[i], ptr3=fx; x2<w2; x2++) {
                        xf = ((float)x2) / sx + ox;
                        r = g = b = s = 0;
                        for (j=0, x=(int)xf-xo; j<w3; j++, x++) {
                            f = *ptr3++;
                            if (x >= 0 && x < w1 && fabs(f) > 1e-8) {
                                ptr4 = line + x + x + x;
                                r += f * *ptr4++;
                                g += f * *ptr4++;
                                b += f * *ptr4++;
                                s += f;
                            }
                        }
                        if (fabs(s) > 1e-3) {
                            *ptr2++ = r;
                            *ptr2++ = g;
                            *ptr2++ = b;
                            *ptr2++ = s;
                        } else {
                            fprintf(stderr, "x factor near zero -- shouldn't happen!\n");
                            ptr4 = line + (int)xf * 3;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = 1.0;
                        }
                    }
                    break;

                default:
                    for (x2=0, ptr2=ptrs[i], ptr3=fx; x2<w2; x2++) {
                        xf = ((float)x2) / sx + ox;
                        for (s=k=0; k<z1; k++)
                            accum[k] = 0;
                        for (j=0, x=(int)xf-xo; j<w3; j++, x++) {
                            f = *ptr3++;
                            if (x >= 0 && x < w1 && fabs(f) > 1e-8) {
                                ptr4 = line + x * z1;
                                for (k=0; k<z1; k++)
                                    accum[k] += f * *ptr4++;
                                s += f;
                            }
                        }
                        if (fabs(s) > 1e-3) {
                            for (k=0; k<z1; k++)
                                *ptr2++ = accum[k];
                            *ptr2++ = s;
                        } else {
                            fprintf(stderr, "x factor near zero -- shouldn't happen!\n");
                            ptr4 = line + (int)xf * z1;
                            for (k=0; k<z1; k++)
                                *ptr2++ = *ptr4++;
                            *ptr2++ = 1.0;
                        }
                    }
                }
/* ------------------------- end switch 1 on z1 ------------------------- */

            }
/* printf("i=%d y2=%d yc=%d y1=%d n1=%d ptrs[i]=%d\n", i, y2, yc, y1, n1, (ptrs[i]-data)/len); */
        }

        /* Now have h3 lines in buffer, starting at y - yo. */
        y1 = (int)yf - yo;
        n1 = h3;

        /* Do vertical part of convolution now.  Finish off calculation for
        /* each output column in this output row by iterating over partial
        /* results for each corresponding input row we calculated above. */
/* ------------------------- start switch 2 on z1 ------------------------- */
        switch (z1) {
        case 1:
            for (x2=0, ptr4=line; x2<w2; x2++) {
                xf = ((float)x2) / sx + ox;
                r = s = 0;
                ptr3 = fy + y2 * h3;
                for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
                    f = *ptr3++;
                    if (y >= 0 && y < h1 && fabs(f) > 1e-8) {
                        ptr1 = ptrs[i] + x2 + x2;
                        r += f * *ptr1++;
                        s += f * *ptr1++;
                    }
/* printf("x2=%d y2=%d i=%d f=%f s=%f (y=%d ptr1=%d)\n", x2, y2, i, f, s, y, (ptr1-data)/len); */
                }
                if (fabs(s) > 1e-3) {
                    *ptr4++ = (c = r / s) > 255 ? 255 : c < 0 ? 0 : c;
                } else {
                    fprintf(stderr, "y factor near zero -- shouldn't happen!\n");
                    ptr1 = ptrs[h3/2] + ((int)xf) * 4;
                    *ptr4++ = *ptr1++;
                }
            }
            break;

        case 3:
            for (x2=0, ptr4=line; x2<w2; x2++) {
                xf = ((float)x2) / sx + ox;
                r = g = b = s = 0;
                ptr3 = fy + y2 * h3;
                for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
                    f = *ptr3++;
                    if (y >= 0 && y < h1 && fabs(f) > 1e-8) {
                        ptr1 = ptrs[i] + x2 * 4;
                        r += f * *ptr1++;
                        g += f * *ptr1++;
                        b += f * *ptr1++;
                        s += f * *ptr1++;
                    }
/* printf("x2=%d y2=%d i=%d f=%f s=%f (y=%d ptr1=%d)\n", x2, y2, i, f, s, y, (ptr1-data)/len); */
                }
                if (fabs(s) > 1e-3) {
                    *ptr4++ = (c = r / s) > 255 ? 255 : c < 0 ? 0 : c;
                    *ptr4++ = (c = g / s) > 255 ? 255 : c < 0 ? 0 : c;
                    *ptr4++ = (c = b / s) > 255 ? 255 : c < 0 ? 0 : c;
                } else {
                    fprintf(stderr, "y factor near zero -- shouldn't happen!\n");
                    ptr1 = ptrs[h3/2] + ((int)xf) * 4;
                    *ptr4++ = *ptr1++;
                    *ptr4++ = *ptr1++;
                    *ptr4++ = *ptr1++;
                }
            }
            break;

        default:
            for (x2=0, ptr4=line; x2<w2; x2++) {
                xf = ((float)x2) / sx + ox;
                for (s=k=0; k<z1; k++)
                    accum[k] = 0;
                ptr3 = fy + y2 * h3;
                for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
                    f = *ptr3++;
                    if (y >= 0 && y < h1 && fabs(f) > 1e-8) {
                        ptr1 = ptrs[i] + x2 * (z1 + 1);
                        for (k=0; k<z1; k++)
                            accum[k] += f * *ptr1++;
                        s += f * *ptr1++;
                    }
/* printf("x2=%d y2=%d i=%d f=%f s=%f (y=%d ptr1=%d)\n", x2, y2, i, f, s, y, (ptr1-data)/len); */
                }
                if (fabs(s) > 1e-3) {
                    for (k=0; k<z1; k++)
                        *ptr4++ = (c = accum[k] / s) > 255 ? 255 : c < 0 ? 0 : c;
                } else {
                    fprintf(stderr, "y factor near zero -- shouldn't happen!\n");
                    ptr1 = ptrs[h3/2] + ((int)xf) * 4;
                    for (k=0; k<z1; k++)
                        *ptr4++ = *ptr1++;
                }
            }
        }
/* ------------------------- end switch 2 on z1 ------------------------- */

        /* Write this output line. */
        jpeg_write_scanlines(&cinfo, &line, 1);
    }

    /* Finish off compression. */
    jpeg_finish_compress(&cinfo);

    /* Clean up. */
    jpeg_destroy_decompress(&dinfo);
    jpeg_destroy_compress(&cinfo);
    free(data);
    free(line);
    free(ptrs);
    free(fx);
    free(accum);
    exit(0);
}
Beispiel #5
0
int
do_search(
    Operation	*op,	/* info about the op to which we're responding */
    SlapReply	*rs	/* all the response data we'll send */ )
{
	struct berval base = BER_BVNULL;
	ber_len_t	siz, off, i;

	Debug( LDAP_DEBUG_TRACE, "%s do_search\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * Parse the search request.  It looks like this:
	 *
	 *	SearchRequest := [APPLICATION 3] SEQUENCE {
	 *		baseObject	DistinguishedName,
	 *		scope		ENUMERATED {
	 *			baseObject	(0),
	 *			singleLevel	(1),
	 *			wholeSubtree (2),
	 *          subordinate (3)  -- OpenLDAP extension
	 *		},
	 *		derefAliases	ENUMERATED {
	 *			neverDerefaliases	(0),
	 *			derefInSearching	(1),
	 *			derefFindingBaseObj	(2),
	 *			alwaysDerefAliases	(3)
	 *		},
	 *		sizelimit	INTEGER (0 .. 65535),
	 *		timelimit	INTEGER (0 .. 65535),
	 *		attrsOnly	BOOLEAN,
	 *		filter		Filter,
	 *		attributes	SEQUENCE OF AttributeType
	 *	}
	 */

	/* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
	if ( ber_scanf( op->o_ber, "{miiiib" /*}*/,
		&base, &op->ors_scope, &op->ors_deref, &op->ors_slimit,
	    &op->ors_tlimit, &op->ors_attrsonly ) == LBER_ERROR )
	{
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto return_results;
	}

	if ( op->ors_tlimit < 0 || op->ors_tlimit > SLAP_MAX_LIMIT ) {
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid time limit" );
		goto return_results;
	}

	if ( op->ors_slimit < 0 || op->ors_slimit > SLAP_MAX_LIMIT ) {
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid size limit" );
		goto return_results;
	}

	switch( op->ors_scope ) {
	case LDAP_SCOPE_BASE:
	case LDAP_SCOPE_ONELEVEL:
	case LDAP_SCOPE_SUBTREE:
	case LDAP_SCOPE_SUBORDINATE:
		break;
	default:
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" );
		goto return_results;
	}

	switch( op->ors_deref ) {
	case LDAP_DEREF_NEVER:
	case LDAP_DEREF_FINDING:
	case LDAP_DEREF_SEARCHING:
	case LDAP_DEREF_ALWAYS:
		break;
	default:
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid deref" );
		goto return_results;
	}

	rs->sr_err = dnPrettyNormal( NULL, &base, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_search: invalid dn: \"%s\"\n",
			op->o_log_prefix, base.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto return_results;
	}

	Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d",
		base.bv_val, op->ors_scope, op->ors_deref );
	Debug( LDAP_DEBUG_ARGS, "    %d %d %d\n",
		op->ors_slimit, op->ors_tlimit, op->ors_attrsonly);

	/* filter - returns a "normalized" version */
	rs->sr_err = get_filter( op, op->o_ber, &op->ors_filter, &rs->sr_text );
	if( rs->sr_err != LDAP_SUCCESS ) {
		if( rs->sr_err == SLAPD_DISCONNECT ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			send_ldap_disconnect( op, rs );
			rs->sr_err = SLAPD_DISCONNECT;
		} else {
			send_ldap_result( op, rs );
		}
		goto return_results;
	}
	filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
	
	Debug( LDAP_DEBUG_ARGS, "    filter: %s\n",
		!BER_BVISEMPTY( &op->ors_filterstr ) ? op->ors_filterstr.bv_val : "empty", 0, 0 );

	/* attributes */
	siz = sizeof(AttributeName);
	off = offsetof(AttributeName,an_name);
	if ( ber_scanf( op->o_ber, "{M}}", &op->ors_attrs, &siz, off ) == LBER_ERROR ) {
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding attrs error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto return_results;
	}
	for ( i=0; i<siz; i++ ) {
		const char *dummy;	/* ignore msgs from bv2ad */
		op->ors_attrs[i].an_desc = NULL;
		op->ors_attrs[i].an_oc = NULL;
		op->ors_attrs[i].an_flags = 0;
		if ( slap_bv2ad( &op->ors_attrs[i].an_name,
			&op->ors_attrs[i].an_desc, &dummy ) != LDAP_SUCCESS )
		{
			slap_bv2undef_ad( &op->ors_attrs[i].an_name,
				&op->ors_attrs[i].an_desc, &dummy,
				SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
		};
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_search: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		goto return_results;
	}

	Debug( LDAP_DEBUG_ARGS, "    attrs:", 0, 0, 0 );

	if ( siz != 0 ) {
		for ( i = 0; i<siz; i++ ) {
			Debug( LDAP_DEBUG_ARGS, " %s", op->ors_attrs[i].an_name.bv_val, 0, 0 );
		}
	}

	Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );

	if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
		char abuf[BUFSIZ/2], *ptr = abuf;
		unsigned len = 0, alen;

		sprintf(abuf, "scope=%d deref=%d", op->ors_scope, op->ors_deref);
		Statslog( LDAP_DEBUG_STATS,
		        "%s SRCH base=\"%s\" %s filter=\"%s\"\n",
		        op->o_log_prefix, op->o_req_dn.bv_val, abuf,
		        op->ors_filterstr.bv_val, 0 );

		for ( i = 0; i<siz; i++ ) {
			alen = op->ors_attrs[i].an_name.bv_len;
			if (alen >= sizeof(abuf)) {
				alen = sizeof(abuf)-1;
			}
			if (len && (len + 1 + alen >= sizeof(abuf))) {
				Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n",
				    op->o_log_prefix, abuf, 0, 0, 0 );
				len = 0;
				ptr = abuf;
			}
			if (len) {
				*ptr++ = ' ';
				len++;
			}
			ptr = lutil_strncopy(ptr, op->ors_attrs[i].an_name.bv_val, alen);
			len += alen;
			*ptr = '\0';
		}
		if (len) {
			Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n",
	    			op->o_log_prefix, abuf, 0, 0, 0 );
		}
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_search( op, rs );

return_results:;
	if ( !BER_BVISNULL( &op->o_req_dn ) ) {
		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
	}
	if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	}
	if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	}
	if ( op->ors_filter != NULL) {
		filter_free_x( op, op->ors_filter, 1 );
	}
	if ( op->ors_attrs != NULL ) {
		op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
Beispiel #6
0
static PyObject *
warn_explicit(PyObject *category, PyObject *message,
              PyObject *filename, int lineno,
              PyObject *module, PyObject *registry, PyObject *sourceline)
{
    PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
    PyObject *item = Py_None;
    PyObject *action;
    int rc;

    /* module can be None if a warning is emitted late during Python shutdown.
       In this case, the Python warnings module was probably unloaded, filters
       are no more available to choose as action. It is safer to ignore the
       warning and do nothing. */
    if (module == Py_None)
        Py_RETURN_NONE;

    if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
        return NULL;
    }

    /* Normalize module. */
    if (module == NULL) {
        module = normalize_module(filename);
        if (module == NULL)
            return NULL;
    }
    else
        Py_INCREF(module);

    /* Normalize message. */
    Py_INCREF(message);  /* DECREF'ed in cleanup. */
    rc = PyObject_IsInstance(message, PyExc_Warning);
    if (rc == -1) {
        goto cleanup;
    }
    if (rc == 1) {
        text = PyObject_Str(message);
        if (text == NULL)
            goto cleanup;
        category = (PyObject*)message->ob_type;
    }
    else {
        text = message;
        message = PyObject_CallFunction(category, "O", message);
        if (message == NULL)
            goto cleanup;
    }

    lineno_obj = PyLong_FromLong(lineno);
    if (lineno_obj == NULL)
        goto cleanup;

    /* Create key. */
    key = PyTuple_Pack(3, text, category, lineno_obj);
    if (key == NULL)
        goto cleanup;

    if ((registry != NULL) && (registry != Py_None)) {
        rc = already_warned(registry, key, 0);
        if (rc == -1)
            goto cleanup;
        else if (rc == 1)
            goto return_none;
        /* Else this warning hasn't been generated before. */
    }

    action = get_filter(category, text, lineno, module, &item);
    if (action == NULL)
        goto cleanup;

    if (PyUnicode_CompareWithASCIIString(action, "error") == 0) {
        PyErr_SetObject(category, message);
        goto cleanup;
    }

    /* Store in the registry that we've been here, *except* when the action
       is "always". */
    rc = 0;
    if (PyUnicode_CompareWithASCIIString(action, "always") != 0) {
        if (registry != NULL && registry != Py_None &&
                PyDict_SetItem(registry, key, Py_True) < 0)
            goto cleanup;
        else if (PyUnicode_CompareWithASCIIString(action, "ignore") == 0)
            goto return_none;
        else if (PyUnicode_CompareWithASCIIString(action, "once") == 0) {
            if (registry == NULL || registry == Py_None) {
                registry = get_once_registry();
                if (registry == NULL)
                    goto cleanup;
            }
            /* _once_registry[(text, category)] = 1 */
            rc = update_registry(registry, text, category, 0);
        }
        else if (PyUnicode_CompareWithASCIIString(action, "module") == 0) {
            /* registry[(text, category, 0)] = 1 */
            if (registry != NULL && registry != Py_None)
                rc = update_registry(registry, text, category, 0);
        }
        else if (PyUnicode_CompareWithASCIIString(action, "default") != 0) {
            PyErr_Format(PyExc_RuntimeError,
                        "Unrecognized action (%R) in warnings.filters:\n %R",
                        action, item);
            goto cleanup;
        }
    }

    if (rc == 1)  /* Already warned for this module. */
        goto return_none;
    if (rc == 0) {
        PyObject *show_fxn = get_warnings_attr("showwarning");
        if (show_fxn == NULL) {
            if (PyErr_Occurred())
                goto cleanup;
            show_warning(filename, lineno, text, category, sourceline);
        }
        else {
            PyObject *res;

            if (!PyCallable_Check(show_fxn)) {
                PyErr_SetString(PyExc_TypeError,
                                "warnings.showwarning() must be set to a "
                                "callable");
                Py_DECREF(show_fxn);
                goto cleanup;
            }

            res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
                                                filename, lineno_obj,
                                                NULL);
            Py_DECREF(show_fxn);
            Py_XDECREF(res);
            if (res == NULL)
                goto cleanup;
        }
    }
    else /* if (rc == -1) */
        goto cleanup;

 return_none:
    result = Py_None;
    Py_INCREF(result);

 cleanup:
    Py_XDECREF(key);
    Py_XDECREF(text);
    Py_XDECREF(lineno_obj);
    Py_DECREF(module);
    Py_XDECREF(message);
    return result;  /* Py_None or NULL. */
}
Beispiel #7
0
int
get_filter(
	Operation *op,
	BerElement *ber,
	Filter **filt,
	const char **text )
{
	ber_tag_t	tag;
	ber_len_t	len;
	int		err;
	Filter		f;

	Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
	/*
	 * A filter looks like this coming in:
	 *	Filter ::= CHOICE {
	 *		and		[0]	SET OF Filter,
	 *		or		[1]	SET OF Filter,
	 *		not		[2]	Filter,
	 *		equalityMatch	[3]	AttributeValueAssertion,
	 *		substrings	[4]	SubstringFilter,
	 *		greaterOrEqual	[5]	AttributeValueAssertion,
	 *		lessOrEqual	[6]	AttributeValueAssertion,
	 *		present		[7]	AttributeType,
	 *		approxMatch	[8]	AttributeValueAssertion,
	 *		extensibleMatch [9]	MatchingRuleAssertion
	 *	}
	 *
	 *	SubstringFilter ::= SEQUENCE {
	 *		type		   AttributeType,
	 *		SEQUENCE OF CHOICE {
	 *			initial		 [0] IA5String,
	 *			any		 [1] IA5String,
	 *			final		 [2] IA5String
	 *		}
	 *	}
	 *
	 *	MatchingRuleAssertion ::= SEQUENCE {
	 *		matchingRule	[1] MatchingRuleId OPTIONAL,
	 *		type		[2] AttributeDescription OPTIONAL,
	 *		matchValue	[3] AssertionValue,
	 *		dnAttributes	[4] BOOLEAN DEFAULT FALSE
	 *	}
	 *
	 */

	tag = ber_peek_tag( ber, &len );

	if( tag == LBER_ERROR ) {
		*text = "error decoding filter";
		return SLAPD_DISCONNECT;
	}

	err = LDAP_SUCCESS;

	f.f_next = NULL;
	f.f_choice = tag; 

	switch ( f.f_choice ) {
	case LDAP_FILTER_EQUALITY:
		Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
		err = get_ava( op, ber, &f, SLAP_MR_EQUALITY, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}

		assert( f.f_ava != NULL );
		break;

	case LDAP_FILTER_SUBSTRINGS:
		Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
		err = get_ssa( op, ber, &f, text );
		if( err != LDAP_SUCCESS ) {
			break;
		}
		assert( f.f_sub != NULL );
		break;

	case LDAP_FILTER_GE:
		Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
		err = get_ava( op, ber, &f, SLAP_MR_ORDERING, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}
		assert( f.f_ava != NULL );
		break;

	case LDAP_FILTER_LE:
		Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
		err = get_ava( op, ber, &f, SLAP_MR_ORDERING, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}
		assert( f.f_ava != NULL );
		break;

	case LDAP_FILTER_PRESENT: {
		struct berval type;

		Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
		if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
			err = SLAPD_DISCONNECT;
			*text = "error decoding filter";
			break;
		}

		f.f_desc = NULL;
		err = slap_bv2ad( &type, &f.f_desc, text );

		if( err != LDAP_SUCCESS ) {
			f.f_choice |= SLAPD_FILTER_UNDEFINED;
			err = slap_bv2undef_ad( &type, &f.f_desc, text,
				SLAP_AD_PROXIED|SLAP_AD_NOINSERT );

			if ( err != LDAP_SUCCESS ) {
				/* unrecognized attribute description or other error */
				Debug( LDAP_DEBUG_ANY, 
					"get_filter: conn %lu unknown attribute "
					"type=%s (%d)\n",
					op->o_connid, type.bv_val, err );

				err = LDAP_SUCCESS;
				f.f_desc = slap_bv2tmp_ad( &type, op->o_tmpmemctx );
			}
			*text = NULL;
		}

		assert( f.f_desc != NULL );
		} break;

	case LDAP_FILTER_APPROX:
		Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
		err = get_ava( op, ber, &f, SLAP_MR_EQUALITY_APPROX, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}
		assert( f.f_ava != NULL );
		break;

	case LDAP_FILTER_AND:
		Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
		err = get_filter_list( op, ber, &f.f_and, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}
		if ( f.f_and == NULL ) {
			f.f_choice = SLAPD_FILTER_COMPUTED;
			f.f_result = LDAP_COMPARE_TRUE;
		}
		/* no assert - list could be empty */
		break;

	case LDAP_FILTER_OR:
		Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
		err = get_filter_list( op, ber, &f.f_or, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}
		if ( f.f_or == NULL ) {
			f.f_choice = SLAPD_FILTER_COMPUTED;
			f.f_result = LDAP_COMPARE_FALSE;
		}
		/* no assert - list could be empty */
		break;

	case LDAP_FILTER_NOT:
		Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
		(void) ber_skip_tag( ber, &len );
		err = get_filter( op, ber, &f.f_not, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}

		assert( f.f_not != NULL );
		if ( f.f_not->f_choice == SLAPD_FILTER_COMPUTED ) {
			int fresult = f.f_not->f_result;
			f.f_choice = SLAPD_FILTER_COMPUTED;
			op->o_tmpfree( f.f_not, op->o_tmpmemctx );
			f.f_not = NULL;

			switch( fresult ) {
			case LDAP_COMPARE_TRUE:
				f.f_result = LDAP_COMPARE_FALSE;
				break;
			case LDAP_COMPARE_FALSE:
				f.f_result = LDAP_COMPARE_TRUE;
				break;
			default: ;
				/* (!Undefined) is Undefined */
			}
		}
		break;

	case LDAP_FILTER_EXT:
		Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );

		err = get_mra( op, ber, &f, text );
		if ( err != LDAP_SUCCESS ) {
			break;
		}

		assert( f.f_mra != NULL );
		break;

	default:
		(void) ber_scanf( ber, "x" ); /* skip the element */
		Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
			f.f_choice, 0, 0 );
		f.f_choice = SLAPD_FILTER_COMPUTED;
		f.f_result = SLAPD_COMPARE_UNDEFINED;
		break;
	}

	if( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
		/* ignore error */
		*text = NULL;
		f.f_choice = SLAPD_FILTER_COMPUTED;
		f.f_result = SLAPD_COMPARE_UNDEFINED;
		err = LDAP_SUCCESS;
	}

	if ( err == LDAP_SUCCESS ) {
		*filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
		**filt = f;
	}

	Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );

	return( err );
}
Image* generate_rendition(Image *const image, ImageInfo const*image_info, char const* spec, char const* rendition_path, ExceptionInfo *exception) {
    unsigned long crop_x;
    unsigned long crop_y;
    unsigned long crop_width;
    unsigned long crop_height;
    unsigned long width;
    unsigned long height;
    unsigned int quality;
    unsigned int resize;
    double blur;
    unsigned int is_progressive;
    Image const* cropped;
    Image *resized;
    RectangleInfo geometry;
    FilterTypes filter;
    ImageInfo *rendition_info;

    if (sscanf(spec, "%lux%lu+%lu+%lu+%lux%lu+%u+%lf+%u+%u", &crop_width, &crop_height, &crop_x, &crop_y, &width, &height, &resize, &blur, &quality, &is_progressive)) {
        if (width > 0 && height > 0) {
            if (crop_width > 0 && crop_height > 0) {
                geometry.x = crop_x;
                geometry.y = crop_y;
                geometry.width = crop_width;
                geometry.height = crop_height;
                cropped = CropImage(image, &geometry, exception);
                if (!cropped) {
                    CatchException(exception);
                    return NULL;
                }
            } else {
                cropped = image;
            }

            filter = get_filter(resize);

            switch (resize) {
            case Sample:
                resized = SampleImage(cropped, width, height, exception);
                break;
            case Scale:
                resized = ScaleImage(cropped, width, height, exception);
                break;
            case Thumbnail:
                resized = ThumbnailImage(cropped, width, height, exception);
                break;
            case Point:
            case Box:
            case Triangle:
            case Hermite:
            case Hanning:
            case Hamming:
            case Blackman:
            case Gaussian:
            case Quadratic:
            case Cubic:
            case Catrom:
            case Mitchell:
            case Lanczos:
            case Bessel:
            case Sinc:
                resized = ResizeImage(cropped, width, height, filter, blur, exception);
                break;
            }

            if (!resized) {
                CatchException(exception);
                return NULL;
            }


            rendition_info = CloneImageInfo(image_info);
            rendition_info->quality = quality;
            strncpy(resized->filename, rendition_path, MaxTextExtent);
            
            if (is_progressive) {
                rendition_info->interlace = LineInterlace;    
                printf("progressive: %s\n", rendition_path);
            }

            if (!WriteImage(rendition_info, resized)) {
                CatchException(exception);
                DestroyImageInfo(rendition_info);
                return NULL;
            }
            printf("wrote %s\n", resized->filename);
            
            DestroyImageInfo(rendition_info);
            return resized;

        }
        
    }

    return NULL;
}