Sergey Vlasov [off-list ref] writes:
However, a straight reuse still will not be possible, because
sha1write_compressed() uses deflateInit(&stream, Z_DEFAULT_COMPRESSION),
which writes zlib headers around the deflate stream, and the zlib footer
contains adler32 checksum. So, as a minimum, you will need to
decompress the object data, calculate its adler32 checksum and write the
zlib header yourself.
Hmph. Thanks for helping, but it sounds like my original plan
was not useful at all. Probably inflating would be still
cheaper than inflating and then deflating, but it would not be
as cool as a straight copy. Sigh...
On Wed, Mar 08, 2006 at 03:04:14AM -0800, Junio C Hamano wrote:
Sergey Vlasov [off-list ref] writes:
quoted
However, a straight reuse still will not be possible, because
sha1write_compressed() uses deflateInit(&stream, Z_DEFAULT_COMPRESSION),
which writes zlib headers around the deflate stream, and the zlib footer
contains adler32 checksum. So, as a minimum, you will need to
decompress the object data, calculate its adler32 checksum and write the
zlib header yourself.
Hmph. Thanks for helping, but it sounds like my original plan
was not useful at all. Probably inflating would be still
cheaper than inflating and then deflating, but it would not be
as cool as a straight copy. Sigh...
Actually you can calculate adler32 checksum of object data from
adler32(header+data) (available at the end of the loose object file),
adler32(header) (which you will need to calculate) and len(data)
(which is available in the header):
#define ADLER32_BASE 65521UL
unsigned int adler32_split(unsigned int adler_full, unsigned int adler_1,
unsigned long len_2)
{
unsigned long s1_1 = adler_1 & 0xffff;
unsigned long s1_2 = (adler_1 >> 16) & 0xffff;
unsigned long rem = len_2 % ADLER32_BASE;
unsigned long s_1_offset = (s1_1 + ADLER32_BASE - 1) % ADLER32_BASE;
unsigned long s_2_offset = (s1_2 + s_1_offset*rem) % ADLER32_BASE;
unsigned long sf_1 = adler_full & 0xffff;
unsigned long sf_2 = (adler_full >> 16) & 0xffff;
unsigned long s2_1 = (sf_1 + ADLER32_BASE - s_1_offset) % ADLER32_BASE;
unsigned long s2_2 = (sf_2 + ADLER32_BASE - s_2_offset) % ADLER32_BASE;
return (s2_2 << 16) | s2_1;
}
However, the resulting code probably won't be pretty...