Răsfoiți Sursa

Store uncompressed if compression was worse

If the data was uncompressible and this deflate implementation expanded
by more than the overhead of simply storing it uncompressed, fall back
to deflate's uncompressed storage mode.  This bounds the maximum deflated
size at the original size plus an overhead of 6 fixed bytes with another
5 bytes per 32767 byte block.

Fixes issue #948.
Andrew Kensler 4 ani în urmă
părinte
comite
db6e91b7d8
1 a modificat fișierele cu 20 adăugiri și 0 ștergeri
  1. 20 0
      stb_image_write.h

+ 20 - 0
stb_image_write.h

@@ -140,6 +140,7 @@ CREDITS:
       Ivan Tikhonov
       Ivan Tikhonov
       github:ignotion
       github:ignotion
       Adam Schackart
       Adam Schackart
+      Andrew Kensler
 
 
 LICENSE
 LICENSE
 
 
@@ -969,6 +970,23 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
       (void) stbiw__sbfree(hash_table[i]);
       (void) stbiw__sbfree(hash_table[i]);
    STBIW_FREE(hash_table);
    STBIW_FREE(hash_table);
 
 
+   // store uncompressed instead if compression was worse
+   if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
+      stbiw__sbn(out) = 2;  // truncate to DEFLATE 32K window and FLEVEL = 1
+      for (j = 0; j < data_len;) {
+         int blocklen = data_len - j;
+         if (blocklen > 32767) blocklen = 32767;
+         stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
+         stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
+         stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
+         stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
+         stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
+         memcpy(out+stbiw__sbn(out), data+j, blocklen);
+         stbiw__sbn(out) += blocklen;
+         j += blocklen;
+      }
+   }
+
    {
    {
       // compute adler32 on input
       // compute adler32 on input
       unsigned int s1=1, s2=0;
       unsigned int s1=1, s2=0;
@@ -1599,6 +1617,8 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
 
 
 /* Revision history
 /* Revision history
+      1.15  (          )
+             make Deflate code emit uncompressed blocks when it would otherwise expand
       1.14  (2020-02-02) updated JPEG writer to downsample chroma channels
       1.14  (2020-02-02) updated JPEG writer to downsample chroma channels
       1.13
       1.13
       1.12
       1.12