/* * Helper routine to bridge to packJPG C++ lib, without changing packJPG itself. */ size_t packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf) { unsigned int len1; uchar_t *pos; /* * Workaround for packJPG limitation, not a bug per se. Images created with * Polaroid cameras appear to have some weird huffman data in the middle which * appears not to be interpreted by any image viewer/editor. This data gets * stripped by packJPG. * So the restored images will be visually correct, but, will be smaller than the * original. So we need to look at the Exif Manufacturer tag for 'Polaroid' and * skip those images. This should be within the first 512 bytes of the * file (really...?) so we do a simple buffer scan without trying to parse Exif * data. */ pos = (uchar_t *)memchr(in_buf, 'P', 512); while (pos) { if (LE64(U64_P(pos)) == POLAROID_LE) return (0); pos++; pos = (uchar_t *)memchr(pos, 'P', 512); } pjglib_init_streams(in_buf, 1, len, *out_buf, 1); len1 = len; if (!pjglib_convert_stream2mem(out_buf, &len1, NULL)) return (0); if (len1 == len) return (0); return (len1); }
int zero_rle_encode(const void *ibuf, const unsigned int ilen, void *obuf, unsigned int *olen) { unsigned int pos1, pos2, sz; unsigned short count; const uchar_t *ib = (const uchar_t *)ibuf; uchar_t *ob = (uchar_t *)obuf; uint64_t val; sz = sizeof (val) - 1; pos2 = 0; for (pos1=0; pos1<ilen && pos2<*olen;) { count = 0; if (ib[pos1] == 0) { /* * We have a run of zeroes. Count them and store only the count. */ while (pos1 < (ilen - sz) && count < (COUNT_MAX - sz)) { val = U64_P(ib+pos1); if (val) break; pos1 += sizeof (val); count += sizeof (val); } for (;pos1<ilen && ib[pos1]==0 && count<COUNT_MAX; pos1++) ++count; count |= ZERO_MASK; U16_P(ob + pos2) = htons(count); pos2 += 2; if (pos2 > *olen) break; } else { unsigned int pos3, pos4, state; pos3 = pos2; pos2 += 2; if (pos2 > *olen) break; state = 0; for (;pos1<ilen && pos2<*olen && count<COUNT_MAX;) { if (ib[pos1] != 0) state = 0; if (ib[pos1] == 0 && !state) { state = 1; // Lookahead if there are at least 4 consecutive zeroes if (ilen > 3) { pos4 = *((unsigned int *)(ib+pos1)); if (!pos4) break; } } ob[pos2++] = ib[pos1++]; ++count; } U16_P(ob + pos3) = htons(count); } } *olen = pos2; if (pos1 < ilen) { return (-1); } else { return (0); } }