Comment #9 on issue 551 by j...@
minteronline.com: VP8L specification contains errors
https://bugs.chromium.org/p/webp/issues/detail?id=551#c9Not sure if there is any progress on this but I found another issue:
In section 3 when describing the color transform:
[code]
void ColorTransform(uint8 red, uint8 blue, uint8 green,
ColorTransformElement *trans,
uint8 *new_red, uint8 *new_blue) {
// Transformed values of red and blue components
uint32 tmp_red = red;
uint32 tmp_blue = blue;
// Applying transform is just adding the transform deltas
tmp_red += ColorTransformDelta(trans->green_to_red, green);
tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
tmp_blue += ColorTransformDelta(trans->red_to_blue, red);
*new_red = tmp_red & 0xff;
*new_blue = tmp_blue & 0xff;
}
[/code]
Note that the original red value is used for the red->blue transform, not the modified red with the green->red transform added. Also, it says that during decoding the inverse transform is used which is shown as:
[code]
void InverseTransform(uint8 red, uint8 green, uint8 blue,
ColorTransformElement *p,
uint8 *new_red, uint8 *new_blue) {
// Applying inverse transform is just subtracting the
// color transform deltas
red -= ColorTransformDelta(p->green_to_red_, green);
blue -= ColorTransformDelta(p->green_to_blue_, green);
blue -= ColorTransformDelta(p->red_to_blue_, red & 0xff);
*new_red = red & 0xff;
*new_blue = blue & 0xff;
}
[/code]
However yet again this is wrong and in the real implementation (libwebp in dsp/lossless.c) the "inverse" decoding transform is the one that adds the delta values (not subtracts like shown in the spec) and the modified red (with the green->red transform added) is used for the red->blue transform:
[code]
void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
const uint32_t* src, int num_pixels,
uint32_t* dst) {
int i;
for (i = 0; i < num_pixels; ++i) {
const uint32_t argb = src[i];
const int8_t green = (int8_t)(argb >> 8);
const uint32_t red = argb >> 16;
int new_red = red & 0xff;
int new_blue = argb & 0xff;
new_red += ColorTransformDelta(m->green_to_red_, green);
new_red &= 0xff;
new_blue += ColorTransformDelta(m->green_to_blue_, green);
new_blue += ColorTransformDelta(m->red_to_blue_, (int8_t)new_red);
new_blue &= 0xff;
dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
}
}
[/code]
The green and predict transforms are correct, and the color-indexing transform seems to be correct but I haven't looked into it that much and I don't have a test image for it yet. Overall though, I have almost-fully implemented the VP8L/lossless half of WebP decoding (except for color-indexing):
https://github.com/matanui159/jebpAlso, even though this probably isn't the correct issue tracker for this but it is related, I have started to work on the VP8/lossy half of my decoder and have already found an issue in THAT spec as well:
In section 9.3 it mentions: the mode of segment feature data (segment_feature_mode), can be absolute-value mode (0) or delta value mode (1).
Which disagrees with section 19.2: segment_feature_mode indicates the feature data update mode, 0 for delta and 1 for the absolute value.
From my understanding the later mention (19.2) is the correct one.