static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, int method, int filter, int reduce_levels, int effort_level, // in [0..6] range uint8_t* const tmp_alpha, VP8BitWriter* const bw, WebPAuxStats* const stats) { int ok = 0; const uint8_t* alpha_src; WebPFilterFunc filter_func; uint8_t header; size_t expected_size; const size_t data_size = width * height; assert((uint64_t)data_size == (uint64_t)width * height); // as per spec assert(filter >= 0 && filter < WEBP_FILTER_LAST); assert(method >= ALPHA_NO_COMPRESSION); assert(method <= ALPHA_LOSSLESS_COMPRESSION); assert(sizeof(header) == ALPHA_HEADER_LEN); // TODO(skal): have a common function and #define's to validate alpha params. expected_size = (method == ALPHA_NO_COMPRESSION) ? (ALPHA_HEADER_LEN + data_size) : (data_size >> 5); header = method | (filter << 2); if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4; VP8BitWriterInit(bw, expected_size); VP8BitWriterAppend(bw, &header, ALPHA_HEADER_LEN); filter_func = WebPFilters[filter]; if (filter_func) { filter_func(data, width, height, 1, width, tmp_alpha); alpha_src = tmp_alpha; } else { alpha_src = data; } if (method == ALPHA_NO_COMPRESSION) { ok = VP8BitWriterAppend(bw, alpha_src, width * height); ok = ok && !bw->error_; } else { ok = EncodeLossless(alpha_src, width, height, effort_level, bw, stats); VP8BitWriterFinish(bw); } return ok; }
// This function always returns an initialized 'bw' object, even upon error. static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, int method, int filter, int reduce_levels, int effort_level, // in [0..6] range uint8_t* const tmp_alpha, FilterTrial* result) { int ok = 0; const uint8_t* alpha_src; WebPFilterFunc filter_func; uint8_t header; const size_t data_size = width * height; const uint8_t* output = NULL; size_t output_size = 0; VP8LBitWriter tmp_bw; assert((uint64_t)data_size == (uint64_t)width * height); // as per spec assert(filter >= 0 && filter < WEBP_FILTER_LAST); assert(method >= ALPHA_NO_COMPRESSION); assert(method <= ALPHA_LOSSLESS_COMPRESSION); assert(sizeof(header) == ALPHA_HEADER_LEN); // TODO(skal): have a common function and #define's to validate alpha params. filter_func = WebPFilters[filter]; if (filter_func != NULL) { filter_func(data, width, height, width, tmp_alpha); alpha_src = tmp_alpha; } else { alpha_src = data; } if (method != ALPHA_NO_COMPRESSION) { ok = VP8LBitWriterInit(&tmp_bw, data_size >> 3); ok = ok && EncodeLossless(alpha_src, width, height, effort_level, &tmp_bw, &result->stats); if (ok) { output = VP8LBitWriterFinish(&tmp_bw); output_size = VP8LBitWriterNumBytes(&tmp_bw); if (output_size > data_size) { // compressed size is larger than source! Revert to uncompressed mode. method = ALPHA_NO_COMPRESSION; VP8LBitWriterDestroy(&tmp_bw); } } else { VP8LBitWriterDestroy(&tmp_bw); return 0; } }