int bits_init (void) { ASSERT (comp_zero == NULL); comp_zero = mem_alloc (BIT_SECTSIZE + 1); if (!comp_zero) return (-1); /* Could not allocate new block */ memset (compressed, BIT_SECTSIZE, 0x00); comp_zero_size = compress_bits (compressed, comp_zero, BIT_SECTSIZE); comp_zero = mem_realloc (comp_zero, comp_zero_size); comp_ones = mem_alloc (BIT_SECTSIZE + 1); if (!comp_ones) { mem_free (comp_ones); return (-1); /* Could not allocate new block */ } memset (compressed, BIT_SECTSIZE, 0xFF); comp_ones_size = compress_bits (compressed, comp_ones, BIT_SECTSIZE); comp_ones = mem_realloc (comp_ones, comp_ones_size); return (0); }
local compress_file_rle (FILE *input, FILE *output) { word in_size, out_size; qbyte signature = RLE_SIGNATURE; fseek (input, 0, SEEK_SET); /* Start from beginning of file */ ASSERT (fwrite (&signature, sizeof (signature), 1, output)); while ((in_size = fread (in_block, 1, BLOCK_SIZE, input)) > 0) { out_size = compress_bits (in_block, out_block, in_size); ASSERT (fwrite (&out_size, 1, sizeof (out_size), output)); ASSERT (fwrite (out_block, 1, out_size, output)); printf ("rle compress: in=%d out=%d\n", in_size, out_size); } }
static int put_section ( BITS *bits, /* Bitstring to work with */ int index, /* Index block number */ int section, /* Section within index */ byte *buffer) /* Buffer to compress */ { BITBLOCK *index_block, /* Points to index block */ *section_block, /* Points to section block */ *section_prev; /* Points to section block */ dbyte block_nbr; /* Entry into block table */ int comp_size, /* Size of compressed data */ copy_from; /* Index into compressed data */ ASSERT (bits); ASSERT (buffer); /* Compress the section and get the resulting size */ index_block = bits-> block [index]; comp_size = compress_bits (buffer, compressed, BIT_SECTSIZE); ASSERT (comp_size <= BIT_SECTSIZE + 1); if (comp_size == comp_zero_size && memcmp (compressed, comp_zero, comp_zero_size) == 0) index_block-> block.index [section] = 0x0000; else if (comp_size == comp_ones_size && memcmp (compressed, comp_ones, comp_ones_size) == 0) index_block-> block.index [section] = 0xFFFF; else { section_prev = NULL; copy_from = 0; while (copy_from < comp_size) /* Slice comp data into blocks */ { if (bits-> free_list) /* Get block from free-list */ { /* if available */ block_nbr = bits-> free_list; bits-> free_list = bits-> block [block_nbr]-> right; } else { /* Allocate new block */ block_nbr = alloc_block (bits); if (block_nbr == 0) /* If no memory left */ return (-1); /* we give up here */ } section_block = bits-> block [block_nbr]; section_block-> right = 0; section_block-> size = min (BIT_DATASIZE, (comp_size - copy_from)); memcpy (section_block-> block.data, compressed + copy_from, section_block-> size); /* Attach block to chain */ if (section_prev) section_prev-> right = block_nbr; else index_block-> block.index [section] = block_nbr; copy_from += section_block-> size; section_prev = section_block; } } return 0; }