Ejemplo n.º 1
0
// Load into a flat array instead of tree
pdf_err pdf_page_tree_load(pdf_doc *d, pdf_obj *o)
{
    int i;
    pdf_obj *a, *kids = o;
    if (o->t == eRef)
    {
        a = pdf_dict_get(o, "Type");
        if (!a)
            return pdf_ok;
        if (obj_is_name(a) && a->value.k)
        {
            if (strcmp(a->value.k, "Pages") == 0)
            {
                kids = pdf_dict_get(o, "Kids");
                if (!kids || ((kids->t != eArray) && (kids->t != eRef)))
                    return pdf_ok;
            }
            else if (strcmp(a->value.k, "Page") == 0)
            {
                pdf_page_load(d, o, &d->pages[d->pageidx]);
                d->pageidx += 1;
                return pdf_ok;
            }
            else
            {
                return pdf_ok;
            }
        }
        else
        {
            return pdf_ok;
        }
    }
    if (kids->t == eDict || kids->t == eRef)
    {
        pdf_page_load(d, kids, &d->pages[d->pageidx]);
        d->pageidx += 1;
    }
    else if (kids->t == eArray)
    {
        for (i = 0; i < kids->value.a.len; i++)
        {
            pdf_obj a;
            a = kids->value.a.items[i];
            if (a.t == eRef)
            {
                pdf_page_tree_load(d, &a);
            }
        }
    }

    return pdf_ok;
}
Ejemplo n.º 2
0
// Load crypt_filter
pdf_err
pdf_cf_load(pdf_encrypt* e, pdf_obj *o, char *name, pdfcrypto_priv **cf)
{
    pdf_obj *a;
    pdfcrypto_algorithm algo;
    authevent event;
    int len;


    *cf = 0;
    if (!o)
        return pdf_ok;
    if (!obj_is_name(o) && o->t != eDict)
        return pdf_ok;
    if (obj_is_name(o) &&
        strcmp(o->value.k, "Identity") == 0)
        return pdf_ok;
    if (obj_is_name(o))
        return pdf_ok;
    a = pdf_dict_get(o, name);
    if (!a)
        return pdf_ok;
    o = a;

    a = pdf_dict_get(o, "CFM");
    algo = eRC4;
    if (a && obj_is_name(a))
    {
        if (strcmp(a->value.k, "V2") == 0)
        {
            algo = eRC4;
        }
        else if (strcmp(a->value.k, "None") == 0)
        {
            algo = eNotBeUsed;
        }
        else if (strcmp(a->value.k, "AESV2") == 0)
        {
            algo = eAESV2;
        }
        else if (strcmp(a->value.k, "AESV3") == 0)
        {
            algo = eAESV3;
        }
        else
        {
            algo = eUnpublished;
        }
    }
    a = pdf_dict_get(o, "AuthEvent");
    if (a && obj_is_name(a))
    {
        if (strcmp(a->value.k, "EFOpen") == 0)
        {
            event = eEFOpen;
        }
        else if (strcmp(a->value.k, "DocOpen") == 0)
        {
            event = eDocOpen;
        }
    }
    len = e->length;
    a = pdf_dict_get(o, "Length");
    if (a && a->t == eInt)
    {
        len = a->value.i*8;
    }
    *cf = pdfcrypto_new(algo, event, len);
    if (!*cf)
        return pdf_mem_err;
    return pdf_ok;
}
Ejemplo n.º 3
0
pdf_err
pdf_istream_filtered_load(pdf_obj* o, void *crypto, int numobj, int numgen, pdf_stream **stm)
{
    pdf_err    e = pdf_ok;
    pdf_filter *last = NULL, *raw = NULL, *crypt = NULL;
    pdf_stream *s = 0;
    sub_stream *ss;
    pdf_obj *x, *xx;
    int m, mm;
    decode_params *dp = 0;

    *stm = 0;

    if (o && o->t == eRef)
    {
        numobj = o->value.r.num;
        numgen = o->value.r.gen;
    }
    else if (o->t != eDict && o->t != eString)
    {
        return pdf_not_ok;
    }

    pdf_obj_resolve(o);
    if (!o) {
        return pdf_not_ok;
    }
    // fill stream info
    if (o->t == eDict)
    {
        int length;
        pdf_obj *len_obj = pdf_dict_get(o, "Length");
        pdf_obj *_decode_params = 0;

        if (!len_obj)
        {
            fprintf(stderr, "%s\n", "Invalid stream.");
            return pdf_not_ok;
        }
        length = pdf_to_int(len_obj);
        s = pdf_malloc(sizeof(pdf_stream));
        if (!s)
            goto fail;
        memset(s, 0, sizeof(pdf_stream));
        s->length = length;
        if (length == 0)
        { // zero lenght stream, just return
            return pdf_stream_zero_length;
        }
        // make raw filter
        /// internal struct. raw stream object
        ss = o->value.d.dict->stream;
        if (!ss)
            goto fail;
        ss->len = s->length;

        _decode_params = pdf_dict_get(o, "DecodeParms");
        if (_decode_params)
        {
            dp = pdf_decode_params_load(_decode_params);
        }
    }
    else if (o->t == eString)
    {
        s = pdf_malloc(sizeof(pdf_stream));
        if (!s)
            goto fail;
        memset(s, 0, sizeof(pdf_stream));
        s->length = o->value.s.len;
        // make string raw filter
        ss = string_stream_new(o->value.s.buf, 0, o->value.s.len, 0, 0);
    }
    else
        goto fail;

    raw = pdf_rawfilter_new(ss);
    // chain crypto filter
    if (crypto)
    {
        if (which_algo(crypto) == eAESV2)
        {
            // need initial_vector
            unsigned char iv[16];
            int n;
            n = (raw->read)(raw, iv, 16);
            crypt = pdf_cryptofilter_new(crypto, numobj, numgen, iv);
        }
        else
        {
            crypt = pdf_cryptofilter_new(crypto, numobj, numgen, NULL);
        }
        if (!crypt)
            goto fail;
        crypt->next = raw;
    }
    if (o->t == eString)
    {
        last = (crypt)?crypt:raw;
        goto done;
    }

    // chain the rest
    x = pdf_dict_get(o, "Filter");
    last = (crypt)?crypt:raw;
    if (!x)
    {
        goto done;
    }
    else
    {
        if (x->t == eArray)
        {
            mm = x->value.a.len;
            xx = x->value.a.items;
        }
        else if (obj_is_name(x))
        {
            mm = 1;
            xx = x;
        }
    }

    for (m = 0; m < mm; m++, xx++)
    {
        pdf_filterkind t = Raw;
        pdf_filter *f;
        if (!obj_is_name(xx))
        {
            break;
        }
        t = pdf_filter_find(xx->value.k);
        if (t == Limit)
        {
            fprintf(stderr, "Unkown filter type: %s\n", xx->value.k);
            continue;
        }
        // make the filter
        switch (t)
        {
            case FlateDecode:
            case LZWDecode:
            case ASCII85Decode:
            case ASCIIHexDecode:
                f = pdf_filter_new(t, last);
                if (!f)
                {
                    if (s)
                        pdf_free(s);
                    if (crypt)
                        PDF_FILTER_CLOSE(crypt, 0); // do not free in_mem stream
                    return pdf_io_err;
                }
                /* chain decoding params filter */
                if (dp && dp->predictor > 1 && (t == FlateDecode || t == LZWDecode))
                {
                    f = pdf_filter_predictor_new(dp, f);
                }
                // make the header of chain
                if (!last)
                {
                    last = f;
                    s->ffilter = f;
                }
                else
                {
#if 0
                    f->next = last;
#endif
                    last = f;
                }
                break;
            default:
                fprintf(stderr, "filter type: %s is not implemented\n", xx->value.k);
                e = pdf_not_ok;
                break;
        }
    }
    if (dp)
        pdf_free(dp);
  done:
    s->ffilter = last;
    s->close = pdf_istream_filtered_close;
    s->write = pdf_istream_filtered_write;
    s->read  = pdf_istream_filtered_read;
    s->getc  = pdf_istream_filtered_getc;
    s->tell  = pdf_istream_filtered_tell;
    s->flush = pdf_stream_base_flush;
    s->seekp = pdf_stream_base_seekp;
    s->seekg = pdf_stream_base_seekg;
    *stm = s;
    return e;
  fail:
    if (s)
        pdf_free(s);
    if (raw)
        raw->close(raw, 1);
    if (dp)
        pdf_free(dp);
    return pdf_not_ok;
}