27 #define _POSIX_C_SOURCE 200809L
31 #include <sys/types.h>
42 #include "tinycthread/source/tinycthread.h"
202 squash_codec_compare (SquashCodec* a, SquashCodec* b) {
206 return strcmp (a->name, b->name);
210 squash_codec_extension_compare (SquashCodec* a, SquashCodec* b) {
214 return strcmp (a->extension, b->extension);
299 assert (codec != NULL);
312 assert (codec != NULL);
314 return codec->priority;
325 assert (codec != NULL);
327 return codec->plugin;
348 return squash_plugin_init_codec (codec->plugin, codec, &(codec->impl));
359 if (codec->initialized != 1) {
360 SquashStatus res = squash_plugin_init_codec (codec->plugin, codec, &(codec->impl));
366 return &(codec->impl);
384 size_t compressed_length,
385 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)]) {
386 SquashCodecImpl* impl = NULL;
388 assert (codec != NULL);
389 assert (compressed_length > 0);
390 assert (compressed != NULL);
393 if (impl != NULL && impl->get_uncompressed_size != NULL) {
394 return impl->get_uncompressed_size (codec, compressed_length, compressed);
401 squash_get_uncompressed_size (
const char* codec,
402 size_t compressed_length,
403 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)]) {
404 assert (codec != NULL);
405 assert (compressed_length > 0);
406 assert (compressed != NULL);
409 if (codec_real == NULL)
434 SquashCodecImpl* impl = NULL;
436 assert (codec != NULL);
439 if (impl != NULL && impl->get_max_compressed_size != NULL) {
440 return impl->get_max_compressed_size (codec, uncompressed_length);
468 if (codec_real == NULL) {
486 SquashCodecImpl* impl = NULL;
488 assert (codec != NULL);
496 if (impl->create_stream != NULL) {
497 return impl->create_stream (codec, stream_type, options);
499 if (impl->process_stream == NULL) {
500 return (SquashStream*) squash_buffer_stream_new (codec, stream_type, options);
519 SquashOptions* options;
521 assert (codec != NULL);
524 va_start (ap, stream_type);
546 size_t* compressed_length,
547 uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)],
548 size_t uncompressed_length,
549 const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)],
550 SquashOptions* options) {
551 SquashCodecImpl* impl = NULL;
553 assert (codec != NULL);
555 assert (compressed != NULL);
556 assert (uncompressed != NULL);
562 if (compressed == uncompressed)
565 if (impl->compress_buffer ||
566 impl->compress_buffer_unsafe) {
569 if (*compressed_length >= max_compressed_length) {
570 if (impl->compress_buffer_unsafe != NULL) {
571 return impl->compress_buffer_unsafe (codec,
572 compressed_length, compressed,
573 uncompressed_length, uncompressed,
576 return impl->compress_buffer (codec,
577 compressed_length, compressed,
578 uncompressed_length, uncompressed,
581 }
else if (impl->compress_buffer != NULL) {
582 return impl->compress_buffer (codec,
583 compressed_length, compressed,
584 uncompressed_length, uncompressed,
588 uint8_t* tmp_buf = malloc (max_compressed_length);
592 status = impl->compress_buffer_unsafe (codec,
593 &max_compressed_length, tmp_buf,
594 uncompressed_length, uncompressed,
597 if (*compressed_length < max_compressed_length) {
598 *compressed_length = max_compressed_length;
602 *compressed_length = max_compressed_length;
603 memcpy (compressed, tmp_buf, max_compressed_length);
614 SquashStream* stream;
620 stream->next_in = uncompressed;
621 stream->avail_in = uncompressed_length;
622 stream->next_out = compressed;
623 stream->avail_out = *compressed_length;
643 *compressed_length = stream->total_out;
664 size_t* compressed_length,
665 uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)],
666 size_t uncompressed_length,
667 const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)],
669 SquashOptions* options;
672 assert (codec != NULL);
674 va_start (ap, uncompressed);
679 compressed_length, compressed,
680 uncompressed_length, uncompressed,
699 size_t* decompressed_length,
700 uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)],
701 size_t compressed_length,
702 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)],
703 SquashOptions* options) {
704 SquashCodecImpl* impl = NULL;
706 assert (codec != NULL);
712 if (decompressed == compressed)
715 if (impl->decompress_buffer != NULL) {
717 res = impl->decompress_buffer (codec,
718 decompressed_length, decompressed,
719 compressed_length, compressed,
725 SquashStream* stream;
728 stream->next_in = compressed;
729 stream->avail_in = compressed_length;
730 stream->next_out = decompressed;
731 stream->avail_out = *decompressed_length;
739 *decompressed_length = stream->total_out;
746 *decompressed_length = stream->total_out;
773 size_t* decompressed_length,
774 uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)],
775 size_t compressed_length,
776 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)],
778 SquashOptions* options;
782 assert (codec != NULL);
784 va_start (ap, compressed);
789 decompressed_length, decompressed,
790 compressed_length, compressed,
812 size_t* compressed_length,
813 uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)],
814 size_t uncompressed_length,
815 const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)],
817 SquashOptions* options;
821 if (codec_real == NULL)
824 va_start (ap, uncompressed);
829 compressed_length, compressed,
830 uncompressed_length, uncompressed,
849 size_t* compressed_length,
850 uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)],
851 size_t uncompressed_length,
852 const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)],
853 SquashOptions* options) {
856 if (codec_real == NULL)
860 compressed_length, compressed,
861 uncompressed_length, uncompressed,
881 size_t* decompressed_length,
882 uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)],
883 size_t compressed_length,
884 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)],
886 SquashOptions* options;
890 if (codec_real == NULL)
893 va_start (ap, compressed);
898 decompressed_length, decompressed,
899 compressed_length, compressed,
917 size_t* decompressed_length,
918 uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)],
919 size_t compressed_length,
920 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)],
921 SquashOptions* options) {
924 if (codec_real == NULL)
928 decompressed_length, decompressed,
929 compressed_length, compressed,
941 squash_codec_new (SquashPlugin* plugin,
const char* name) {
942 SquashCodec* codecp = (SquashCodec*) malloc (
sizeof (SquashCodec));
943 SquashCodec codec = { 0, };
945 codec.plugin = plugin;
946 codec.name = strdup (name);
948 SQUASH_TREE_ENTRY_INIT(codec.tree);
965 squash_codec_set_extension (SquashCodec* codec,
const char* extension) {
966 if (codec->extension != NULL)
967 free (codec->extension);
969 codec->extension = (extension != NULL) ? strdup (extension) : NULL;
980 return codec->extension;
991 squash_codec_set_priority (SquashCodec* codec,
unsigned int priority) {
992 codec->priority = priority;
1003 return codec->impl.info;
1017 if (codec_real != NULL) {
1031 const SquashOptionInfo*
1034 return SQUASH_LIKELY(impl != NULL) ? impl->options : NULL;
1043 const SquashOptionInfo*
1047 if (codec_real != NULL)
1053 static const SquashOptionValue*
1054 squash_codec_get_option_value_by_name (SquashCodec* codec,
1055 SquashOptions* options,
1057 SquashOptionType* type) {
1059 const SquashOptionInfo* info;
1061 assert (codec != NULL);
1062 assert (key != NULL);
1065 for (c_option = 0 ; info[c_option].name != NULL ; c_option++) {
1066 if (strcasecmp (key, info[c_option].name) == 0) {
1068 *type = info[c_option].type;
1069 return (options != NULL) ?
1070 &(options->values[c_option]) :
1071 &(info[c_option].default_value);
1076 *type = SQUASH_OPTION_TYPE_NONE;
1094 SquashOptions* options,
1096 SquashOptionType type;
1097 const SquashOptionValue* value = squash_codec_get_option_value_by_name (codec, options, key, &type);
1098 switch ((
int) type) {
1099 case SQUASH_OPTION_TYPE_STRING:
1100 return value->string_value;
1102 squash_assert_unreachable();
1120 SquashOptions* options,
1122 if (options != NULL)
1123 return options->values[index].string_value;
1125 return codec->impl.options[index].default_value.string_value;
1142 SquashOptions* options,
1144 SquashOptionType type;
1145 const SquashOptionValue* value = squash_codec_get_option_value_by_name (codec, options, key, &type);
1146 switch ((
int) type) {
1147 case SQUASH_OPTION_TYPE_BOOL:
1148 return value->bool_value;
1150 squash_assert_unreachable();
1168 SquashOptions* options,
1170 if (options != NULL)
1171 return options->values[index].bool_value;
1173 return codec->impl.options[index].default_value.bool_value;
1190 SquashOptions* options,
1192 SquashOptionType type;
1193 const SquashOptionValue* value = squash_codec_get_option_value_by_name (codec, options, key, &type);
1194 switch ((
int) type) {
1195 case SQUASH_OPTION_TYPE_INT:
1196 case SQUASH_OPTION_TYPE_RANGE_INT:
1197 case SQUASH_OPTION_TYPE_ENUM_STRING:
1198 return value->int_value;
1200 squash_assert_unreachable();
1218 SquashOptions* options,
1220 if (options != NULL)
1221 return options->values[index].int_value;
1223 return codec->impl.options[index].default_value.int_value;
1240 SquashOptions* options,
1242 SquashOptionType type;
1243 const SquashOptionValue* value = squash_codec_get_option_value_by_name (codec, options, key, &type);
1244 switch ((
int) type) {
1245 case SQUASH_OPTION_TYPE_SIZE:
1246 case SQUASH_OPTION_TYPE_RANGE_SIZE:
1247 return value->size_value;
1249 squash_assert_unreachable();
1267 SquashOptions* options,
1269 if (options != NULL)
1270 return options->values[index].size_value;
1272 return codec->impl.options[index].default_value.size_value;
SquashStream * squash_codec_create_stream_with_options(SquashCodec *codec, SquashStreamType stream_type, SquashOptions *options)
Create a new stream with existing SquashOptions.
size_t squash_codec_get_option_size(SquashCodec *codec, SquashOptions *options, const char *key)
Get the size value for an option.
size_t squash_get_max_compressed_size(const char *codec, size_t uncompressed_length)
Get the maximum buffer size necessary to store compressed data.
bool squash_codec_get_option_bool(SquashCodec *codec, SquashOptions *options, const char *key)
Get the boolean value for an option.
const char * squash_codec_get_option_string_index(SquashCodec *codec, SquashOptions *options, size_t index)
Get the string value for an option by index.
SquashStatus squash_stream_finish(SquashStream *stream)
Finish writing to a stream.
const SquashOptionInfo * squash_get_option_info(const char *codec)
Get a list of options applicable to the codec.
SquashCodec * squash_get_codec(const char *codec)
Retrieve a SquashCodec.
SquashCodecInfo squash_get_info(const char *codec)
Get a bitmask of information about the codec.
bool squash_codec_get_option_bool_index(SquashCodec *codec, SquashOptions *options, size_t index)
Get the boolean value for an option by index.
SquashCodecInfo
Information about the codec.
#define SQUASH_CODEC_INFO_INVALID
Invalid codec.
SquashStatus squash_decompress(const char *codec, size_t *decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)],...)
Decompress a buffer with an existing SquashOptions.
SquashStatus squash_codec_compress(SquashCodec *codec, size_t *compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)],...)
Compress a buffer.
A buffer passed to squash was invalid.
Reached the end of the stream while decoding.
const char * squash_codec_get_extension(SquashCodec *codec)
Get the codec's extension.
SquashPlugin * squash_codec_get_plugin(SquashCodec *codec)
Get the plugin associated with a codec.
Operation partially completed.
SquashOptions * squash_options_newv(SquashCodec *codec, va_list options)
Create a new group of options from a variadic list.
The requested codec could not be found.
size_t squash_codec_get_uncompressed_size(SquashCodec *codec, size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)])
Get the uncompressed size of the compressed buffer.
SquashStream * squash_codec_create_stream(SquashCodec *codec, SquashStreamType stream_type,...)
Create a new stream with existing SquashOptions.
size_t squash_codec_get_option_size_index(SquashCodec *codec, SquashOptions *options, size_t index)
Get the size value for an option by index.
SquashStatus squash_compress_with_options(const char *codec, size_t *compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions *options)
Compress a buffer with an existing SquashOptions.
SquashStatus squash_codec_init(SquashCodec *codec)
Initialize a codec.
SquashCodecImpl * squash_codec_get_impl(SquashCodec *codec)
Get the codec's function table.
Insufficient space in buffer.
SquashStatus squash_compress(const char *codec, size_t *compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)],...)
Compress a buffer.
void * squash_object_unref(void *obj)
Decrement the reference count on an object.
int squash_codec_get_option_int(SquashCodec *codec, SquashOptions *options, const char *key)
Get the integer value for an option.
size_t squash_codec_get_max_compressed_size(SquashCodec *codec, size_t uncompressed_length)
Get the maximum buffer size necessary to store compressed data.
const char * squash_codec_get_name(SquashCodec *codec)
Get the name of a SquashCodec.
SquashStatus squash_codec_compress_with_options(SquashCodec *codec, size_t *compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions *options)
Compress a buffer with an existing SquashOptions.
SquashStatus squash_decompress_with_options(const char *codec, size_t *decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions *options)
Decompress a buffer.
Not enough memory is available.
const char * squash_codec_get_option_string(SquashCodec *codec, SquashOptions *options, const char *key)
Get the string value for an option.
SquashStatus squash_codec_decompress_with_options(SquashCodec *codec, size_t *decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions *options)
Decompress a buffer with an existing SquashOptions.
const SquashOptionInfo * squash_codec_get_option_info(SquashCodec *codec)
Get a list of options applicable to the codec.
SquashStatus
Status codes.
SquashStatus squash_error(SquashStatus status)
Emit an error.
SquashStatus squash_codec_decompress(SquashCodec *codec, size_t *decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)],...)
Decompress a buffer.
void * squash_object_ref(void *obj)
Increment the reference count on an object.
unsigned int squash_codec_get_priority(SquashCodec *codec)
Get the priority of a SquashCodec.
SquashStatus squash_stream_process(SquashStream *stream)
Process a stream.
SquashCodecInfo squash_codec_get_info(SquashCodec *codec)
Get a bitmask of information about the codec.
Unable to load the requested resource.
Operation completed successfully.
int squash_codec_get_option_int_index(SquashCodec *codec, SquashOptions *options, size_t index)
Get the integer value for an option by index.
SquashStreamType
Stream type.