diff options
Diffstat (limited to 'deflate.c')
-rw-r--r-- | deflate.c | 90 |
1 files changed, 63 insertions, 27 deletions
@@ -323,43 +323,68 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) | |||
323 | uInt dictLength; | 323 | uInt dictLength; |
324 | { | 324 | { |
325 | deflate_state *s; | 325 | deflate_state *s; |
326 | uInt length = dictLength; | 326 | uInt str, n; |
327 | uInt n; | 327 | int wrap; |
328 | IPos hash_head = 0; | 328 | unsigned avail; |
329 | unsigned char *next; | ||
329 | 330 | ||
330 | if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || | 331 | if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) |
331 | strm->state->wrap == 2 || | ||
332 | (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) | ||
333 | return Z_STREAM_ERROR; | 332 | return Z_STREAM_ERROR; |
334 | |||
335 | s = strm->state; | 333 | s = strm->state; |
336 | if (s->wrap) | 334 | wrap = s->wrap; |
337 | strm->adler = adler32(strm->adler, dictionary, dictLength); | 335 | if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) |
336 | return Z_STREAM_ERROR; | ||
338 | 337 | ||
339 | if (length < MIN_MATCH) return Z_OK; | 338 | /* when using zlib wrappers, compute Adler-32 for provided dictionary */ |
340 | if (length > s->w_size) { | 339 | if (wrap == 1) |
341 | length = s->w_size; | 340 | strm->adler = adler32(strm->adler, dictionary, dictLength); |
342 | dictionary += dictLength - length; /* use the tail of the dictionary */ | 341 | s->wrap = 0; /* avoid computing Adler-32 in read_buf */ |
342 | |||
343 | /* if dictionary would fill window, just replace the history */ | ||
344 | if (dictLength >= s->w_size) { | ||
345 | if (wrap == 0) { /* already empty otherwise */ | ||
346 | CLEAR_HASH(s); | ||
347 | s->strstart = 0; | ||
348 | s->block_start = 0L; | ||
349 | } | ||
350 | dictionary += dictLength - s->w_size; /* use the tail */ | ||
351 | dictLength = s->w_size; | ||
343 | } | 352 | } |
344 | zmemcpy(s->window, dictionary, length); | ||
345 | s->strstart = length; | ||
346 | s->block_start = (long)length; | ||
347 | 353 | ||
348 | /* Insert all strings in the hash table (except for the last two bytes). | 354 | /* insert dictionary into window and hash */ |
349 | * s->lookahead stays null, so s->ins_h will be recomputed at the next | 355 | avail = strm->avail_in; |
350 | * call of fill_window. | 356 | next = strm->next_in; |
351 | */ | 357 | strm->avail_in = dictLength; |
352 | s->ins_h = s->window[0]; | 358 | strm->next_in = (Bytef *)dictionary; |
353 | UPDATE_HASH(s, s->ins_h, s->window[1]); | 359 | fill_window(s); |
354 | for (n = 0; n <= length - MIN_MATCH; n++) { | 360 | while (s->lookahead >= MIN_MATCH) { |
355 | INSERT_STRING(s, n, hash_head); | 361 | str = s->strstart; |
362 | n = s->lookahead - (MIN_MATCH-1); | ||
363 | do { | ||
364 | UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); | ||
365 | #ifndef FASTEST | ||
366 | s->prev[str & s->w_mask] = s->head[s->ins_h]; | ||
367 | #endif | ||
368 | s->head[s->ins_h] = (Pos)str; | ||
369 | str++; | ||
370 | } while (--n); | ||
371 | s->strstart = str; | ||
372 | s->lookahead = MIN_MATCH-1; | ||
373 | fill_window(s); | ||
356 | } | 374 | } |
357 | if (hash_head) hash_head = 0; /* to make compiler happy */ | 375 | s->strstart += s->lookahead; |
376 | s->block_start = (long)s->strstart; | ||
377 | s->lookahead = 0; | ||
378 | s->match_length = s->prev_length = MIN_MATCH-1; | ||
379 | s->match_available = 0; | ||
380 | strm->next_in = next; | ||
381 | strm->avail_in = avail; | ||
382 | s->wrap = wrap; | ||
358 | return Z_OK; | 383 | return Z_OK; |
359 | } | 384 | } |
360 | 385 | ||
361 | /* ========================================================================= */ | 386 | /* ========================================================================= */ |
362 | int ZEXPORT deflateReset (strm) | 387 | int ZEXPORT deflateResetKeep (strm) |
363 | z_streamp strm; | 388 | z_streamp strm; |
364 | { | 389 | { |
365 | deflate_state *s; | 390 | deflate_state *s; |
@@ -389,12 +414,23 @@ int ZEXPORT deflateReset (strm) | |||
389 | s->last_flush = Z_NO_FLUSH; | 414 | s->last_flush = Z_NO_FLUSH; |
390 | 415 | ||
391 | _tr_init(s); | 416 | _tr_init(s); |
392 | lm_init(s); | ||
393 | 417 | ||
394 | return Z_OK; | 418 | return Z_OK; |
395 | } | 419 | } |
396 | 420 | ||
397 | /* ========================================================================= */ | 421 | /* ========================================================================= */ |
422 | int ZEXPORT deflateReset (strm) | ||
423 | z_streamp strm; | ||
424 | { | ||
425 | int ret; | ||
426 | |||
427 | ret = deflateResetKeep(strm); | ||
428 | if (ret == Z_OK) | ||
429 | lm_init(strm->state); | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | /* ========================================================================= */ | ||
398 | int ZEXPORT deflateSetHeader (strm, head) | 434 | int ZEXPORT deflateSetHeader (strm, head) |
399 | z_streamp strm; | 435 | z_streamp strm; |
400 | gz_headerp head; | 436 | gz_headerp head; |