void * pdf_finditem(pdf_store *store, pdf_itemkind kind, fz_obj *key) { pdf_item *item; struct refkey refkey; if (key == nil) return nil; if (fz_isindirect(key)) { refkey.kind = kind; refkey.oid = fz_tonum(key); refkey.gen = fz_togen(key); item = fz_hashfind(store->hash, &refkey); if (item) { item->age = 0; return item->val; } } else { for (item = store->root; item; item = item->next) if (item->kind == kind && !fz_objcmp(item->key, key)) { item->age = 0; return item->val; } } return nil; }
void pdf_removeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key) { pdf_item *item, *prev; struct refkey refkey; if (key == nil) return; if (fz_isindirect(key)) { refkey.kind = kind; refkey.oid = fz_tonum(key); refkey.gen = fz_togen(key); item = fz_hashfind(store->hash, &refkey); if (!item) return; fz_hashremove(store->hash, &refkey); pdf_logrsrc("remove item %s (%d %d R) ptr=%p\n", kindstr(kind), fz_tonum(key), fz_togen(key), item->val); dropitem(kind, item->val); fz_dropobj(item->key); fz_free(item); } else { prev = nil; for (item = store->root; item; item = item->next) { if (item->kind == kind && !fz_objcmp(item->key, key)) { if (!prev) store->root = item->next; else prev->next = item->next; dropitem(kind, item->val); fz_dropobj(item->key); fz_free(item); break; } prev = item; } } }
void pdf_evictageditems(pdf_store *store) { pdf_item *item; pdf_item *next; pdf_item *prev; struct refkey *key; int i; for (i = 0; i < fz_hashlen(store->hash); i++) { key = fz_hashgetkey(store->hash, i); item = fz_hashfind(store->hash, key); if (item && item->age > itemmaxage(item->kind)) { fz_hashremove(store->hash, key); evictitem(item); } } prev = nil; for (item = store->root; item; item = next) { next = item->next; if (item->age > itemmaxage(item->kind)) { if (!prev) store->root = next; else prev->next = next; evictitem(item); } else prev = item; } }
static void fz_stdconvpixmap(fz_pixmap *src, fz_pixmap *dst) { float srcv[FZ_MAXCOLORS]; float dstv[FZ_MAXCOLORS]; int srcn, dstn; int y, x, k, i; fz_colorspace *ss = src->colorspace; fz_colorspace *ds = dst->colorspace; unsigned char *s = src->samples; unsigned char *d = dst->samples; assert(src->w == dst->w && src->h == dst->h); assert(src->n == ss->n + 1); assert(dst->n == ds->n + 1); srcn = ss->n; dstn = ds->n; /* Special case for Lab colorspace (scaling of components to float) */ if (!strcmp(ss->name, "Lab") && srcn == 3) { for (y = 0; y < src->h; y++) { for (x = 0; x < src->w; x++) { srcv[0] = *s++ / 255.0f * 100; srcv[1] = *s++ - 128; srcv[2] = *s++ - 128; fz_convertcolor(ss, srcv, ds, dstv); for (k = 0; k < dstn; k++) *d++ = dstv[k] * 255; *d++ = *s++; } } } /* Brute-force for small images */ else if (src->w * src->h < 256) { for (y = 0; y < src->h; y++) { for (x = 0; x < src->w; x++) { for (k = 0; k < srcn; k++) srcv[k] = *s++ / 255.0f; fz_convertcolor(ss, srcv, ds, dstv); for (k = 0; k < dstn; k++) *d++ = dstv[k] * 255; *d++ = *s++; } } } /* 1-d lookup table for separation and similar colorspaces */ else if (srcn == 1) { unsigned char lookup[FZ_MAXCOLORS * 256]; for (i = 0; i < 256; i++) { srcv[0] = i / 255.0f; fz_convertcolor(ss, srcv, ds, dstv); for (k = 0; k < dstn; k++) lookup[i * dstn + k] = dstv[k] * 255; } for (y = 0; y < src->h; y++) { for (x = 0; x < src->w; x++) { i = *s++; for (k = 0; k < dstn; k++) *d++ = lookup[i * dstn + k]; *d++ = *s++; } } } /* Memoize colors using a hash table for the general case */ else { fz_hashtable *lookup; unsigned char *color; lookup = fz_newhash(509, srcn); for (y = 0; y < src->h; y++) { for (x = 0; x < src->w; x++) { color = fz_hashfind(lookup, s); if (color) { memcpy(d, color, dstn); s += srcn; d += dstn; *d++ = *s++; } else { for (k = 0; k < srcn; k++) srcv[k] = *s++ / 255.0f; fz_convertcolor(ss, srcv, ds, dstv); for (k = 0; k < dstn; k++) *d++ = dstv[k] * 255; fz_hashinsert(lookup, s - srcn, d - dstn); *d++ = *s++; } } } fz_freehash(lookup); } }