void ZopfliBlockSplitLZ77(const ZopfliOptions* options, const ZopfliLZ77Store* lz77, size_t maxblocks, size_t** splitpoints, size_t* npoints) { size_t lstart, lend; size_t i; size_t llpos = 0; size_t numblocks = 1; unsigned char* done; double splitcost, origcost; if (lz77->size < 10) return; /* This code fails on tiny files. */ done = (unsigned char*)malloc(lz77->size); if (!done) exit(-1); /* Allocation failed. */ for (i = 0; i < lz77->size; i++) done[i] = 0; lstart = 0; lend = lz77->size; for (;;) { SplitCostContext c; if (maxblocks > 0 && numblocks >= maxblocks) { break; } c.lz77 = lz77; c.start = lstart; c.end = lend; assert(lstart < lend); llpos = FindMinimum(SplitCost, &c, lstart + 1, lend, &splitcost); assert(llpos > lstart); assert(llpos < lend); origcost = EstimateCost(lz77, lstart, lend); if (splitcost > origcost || llpos == lstart + 1 || llpos == lend) { done[lstart] = 1; } else { AddSorted(llpos, splitpoints, npoints); numblocks++; } if (!FindLargestSplittableBlock( lz77->size, done, *splitpoints, *npoints, &lstart, &lend)) { break; /* No further split will probably reduce compression. */ } if (lend - lstart < 10) { break; } } if (options->verbose) { PrintBlockSplitPoints(lz77, *splitpoints, *npoints); } free(done); }
void ZopfliBlockSplitLZ77(const ZopfliOptions* options, const unsigned short* litlens, const unsigned short* dists, size_t llsize, size_t maxblocks, size_t** splitpoints, size_t* npoints, size_t startnpoints) { size_t lstart, lend; size_t i; size_t llpos = 0; size_t numblocks = 1; unsigned char* done; double splitcost, origcost; if (llsize < 10) return; /* This code fails on tiny files. */ done = (unsigned char*)malloc(llsize); if (!done) exit(-1); /* Allocation failed. */ for (i = 0; i < llsize; i++) done[i] = 0; lstart = 0; lend = llsize; for (;;) { SplitCostContext c; if (maxblocks > 0 && numblocks >= maxblocks) { break; } c.litlens = litlens; c.dists = dists; c.llsize = llsize; c.start = lstart; c.end = lend; c.ohh = options->optimizehuffmanheader; assert(lstart < lend); llpos = FindMinimum(SplitCost, &c, lstart + 1, lend,options); assert(llpos > lstart); assert(llpos < lend); splitcost = EstimateCost(litlens, dists, lstart, llpos, c.ohh) + EstimateCost(litlens, dists, llpos, lend, c.ohh); origcost = EstimateCost(litlens, dists, lstart, lend, c.ohh); if (splitcost > origcost || llpos == lstart + 1 || llpos == lend) { done[lstart] = 1; } else { AddSorted(llpos, splitpoints, npoints); ++numblocks; if(options->verbose>0 && options->verbose<5) fprintf(stderr,"Initializing blocks: %lu \r",(unsigned long)(startnpoints+numblocks)); } if (!FindLargestSplittableBlock( llsize, done, *splitpoints, *npoints, &lstart, &lend)) { break; /* No further split will probably reduce compression. */ } if (lend - lstart < 10) { break; } } if (options->verbose>3) { PrintBlockSplitPoints(litlens, dists, llsize, *splitpoints, *npoints); } if(options->verbose>2) { fprintf(stderr, "Total blocks: %lu \n\n",(unsigned long)numblocks); } free(done); }