Example #1
0
pdf_annots*
pdf_annots_load(pdf_obj* o)
{
    pdf_annots *a=NULL, *first=NULL, *last = NULL;
    int i;
    pdf_obj *x, *t;

    o = pdf_array_get(o);
    if (!o)
        return NULL;

    for (i = 0; i < pdf_to_arraylen(o); i++)
    {
        t = pdf_get_array_item(o, i);
        pdf_obj_resolve(t);
        if (!t || t->t != eDict)
            continue;
        a = pdf_malloc(sizeof(pdf_annots));
        if (!a)
            return NULL;
        memset(a, 0, sizeof(pdf_annots));
        // default border
        a->border[0] = 0, a->border[1] = 0, a->border[2] = 1;
        // load annotation node
        a->subtype = pdf_annots_type(pdf_dict_get(t, "Subtype"));
        a->rect = pdf_rect_get(pdf_dict_get(t, "Rect"));
        if ((x = pdf_dict_get(t, "Border"))) {
            a->border[0] = pdf_to_float(pdf_get_array_item(x, 0));
            a->border[1] = pdf_to_float(pdf_get_array_item(x, 1));
            a->border[2] = pdf_to_float(pdf_get_array_item(x, 2));
            if (pdf_to_arraylen(x) > 3) {
                pdf_obj *y = pdf_get_array_item(x, 3);
                a->border[3] =  pdf_to_float(pdf_get_array_item(y, 0));
                a->border[4] =  pdf_to_float(pdf_get_array_item(y, 1));
            }
        }
        // make linked list
        if (last)
            last->next = a;
        if (i == 0)
        {
            first = a;
        }
        last = a;
    }
    return first;
}
Example #2
0
pdf_err
pdf_encrypt_load(pdf_obj *o, pdf_encrypt **encrypt)
{
    pdf_obj *a;
    pdf_encrypt *e;
    if (!o)
        return pdf_ok;
    pdf_obj_resolve(o);
    if (!o)
        return pdf_ok;
    *encrypt = pdf_malloc(sizeof(pdf_encrypt));
    if (!*encrypt)
        return pdf_mem_err;
    memset(*encrypt, 0, sizeof(pdf_encrypt));
    e = *encrypt;
    e->v = 0;
    a = pdf_dict_get(o, "Filter");
    if (a)
    {
        pdf_obj_resolve(a);
        (*encrypt)->filter = pdf_malloc(strlen(a->value.k)+1);
        memcpy((*encrypt)->filter, a->value.k, strlen(a->value.k));
        (*encrypt)->filter[strlen(a->value.k)] = 0;
    }
    a = pdf_dict_get(o, "SubFilter");
    if (a)
    {
        pdf_obj_resolve(a);
        (*encrypt)->subfilter = pdf_malloc(strlen(a->value.k)+1);
        memcpy((*encrypt)->subfilter, a->value.k, strlen(a->value.k));
        (*encrypt)->subfilter[strlen(a->value.k)] = 0;
    }
    a = pdf_dict_get(o, "V");
    if (a)
    {
        (*encrypt)->v = pdf_to_int(a);
    }
    e->length = 40;
    a = pdf_dict_get(o, "Length");
    if (a)
    {
        (*encrypt)->length = pdf_to_int(a);
    }
    if (e->v == 4)
    {
        pdf_obj *cf = pdf_dict_get(o, "CF");
        if (cf)
        {
            a = pdf_dict_get(o, "StmF");
            if (a)
            {
                pdf_obj_resolve(a);
                pdf_cf_load(e, cf, a->value.k, &e->stmf);
            }
            a = pdf_dict_get(o, "StrF");
            if (a)
            {
                pdf_obj_resolve(a);
                pdf_cf_load(e, cf, a->value.k, &e->strf);
            }
            a = pdf_dict_get(o, "EFF");
            if (a)
            {
                pdf_obj_resolve(a);
                pdf_cf_load(e, cf, a->value.k, &e->eff);
            }
        }
    }

    // standard encryption dictionary (items)
    a = pdf_dict_get(o, "R");
    if (a)
    {
        (*encrypt)->r = pdf_to_int(a);
    }
    a = pdf_dict_get(o, "O"); // owner password
    if (a)
    {
        // should verify length to 32 bytes
        pdf_obj_resolve(a);
        memcpy((*encrypt)->o, a->value.s.buf, a->value.s.len);
    }
    a = pdf_dict_get(o, "U"); // user password
    if (a)
    {
        // should verify length to 32 bytes
        pdf_obj_resolve(a);
        memcpy((*encrypt)->u, a->value.s.buf, a->value.s.len);
    }
    a = pdf_dict_get(o, "P"); // permission flags
    if (a)
    {
        (*encrypt)->p = pdf_to_int(a);
    }
    a = pdf_dict_get(o, "EncryptMetadata");
    if (a)
    {
        pdf_obj_resolve(a);
        (*encrypt)->encrypt_metadata = a->value.b;
    }

    return pdf_ok;
}
Example #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;
}