2015-12-27 20:28:09 +00:00
|
|
|
/*
|
|
|
|
* QuickTime palette handling
|
|
|
|
* Copyright (c) 2001 Fabrice Bellard
|
|
|
|
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
|
|
|
|
* Copyright (c) 2015 Mats Peterson
|
|
|
|
*
|
|
|
|
* This file is part of FFmpeg.
|
|
|
|
*
|
|
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "avformat.h"
|
|
|
|
#include "libavutil/intreadwrite.h"
|
|
|
|
#include "qtpalette.h"
|
|
|
|
|
|
|
|
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
|
|
|
|
{
|
|
|
|
int tmp, bit_depth, color_table_id, greyscale, i;
|
|
|
|
|
|
|
|
avio_seek(pb, 82, SEEK_CUR);
|
|
|
|
|
|
|
|
/* Get the bit depth and greyscale state */
|
|
|
|
tmp = avio_rb16(pb);
|
|
|
|
bit_depth = tmp & 0x1F;
|
|
|
|
greyscale = tmp & 0x20;
|
|
|
|
|
|
|
|
/* Get the color table ID */
|
|
|
|
color_table_id = avio_rb16(pb);
|
|
|
|
|
|
|
|
/* Do not create a greyscale palette for Cinepak */
|
|
|
|
if (greyscale && codec_id == AV_CODEC_ID_CINEPAK)
|
|
|
|
return 0;
|
|
|
|
|
2015-12-29 06:35:00 +00:00
|
|
|
/* If the depth is 1, 2, 4, or 8 bpp, file is palettized. */
|
|
|
|
if ((bit_depth == 1 || bit_depth == 2 || bit_depth == 4 || bit_depth == 8)) {
|
2016-01-10 09:53:33 +00:00
|
|
|
uint32_t color_count, color_start, color_end;
|
2018-04-19 18:11:02 +00:00
|
|
|
uint32_t r, g, b;
|
2015-12-27 20:28:09 +00:00
|
|
|
|
lavf/qtpalette: Ignore greyscale bit in certain cases
The QuickTime File Format Specification states the following:
"Depth: A 16-bit integer that indicates the pixel depth of the
compressed image. Values of 1, 2, 4, 8 ,16, 24, and 32 indicate the
depth of color images. The value 32 should be used only if the image
contains an alpha channel. Values of 34, 36, and 40 indicate 2-, 4-, and
8-bit grayscale, respectively, for grayscale images."
There is no mention of value 33, i.e. 1-bit video (0x01) with the
greyscale bit (0x20) set. I therefore suggest that we ignore the
greyscale bit when processing 1-bit video. Another reason to do this is
that the first 1-bit sample file below will be displayed properly with
blue colors in QuickTime in Windows or Mac *in spite of* the greyscale
bit being set.
Also, QuickTime in Windows or Mac ignores the greyscale bit if the
video sample description contains a palette, regardless of bit depth.
This is undocumented behaviour, but I think we should do the same, and
it seems pretty logical after all, since one wouldn't really bother
putting a customized palette into a grayscale file anyway. See the
second 8-bit sample file below, which has the greyscale bit set, and
which contains a palette in the video sample description. In Windows or
Mac, it will be displayed with the palette in the sample description, in
spite of the greyscale bit being set.
Sample file 1 (1-bit QuickTime Animation):
https://drive.google.com/open?id=0B3_pEBoLs0faTThSek1EeXQ0ZHM
Earth Spin 1-bit qtrle orig.mov
Sample file 2 (8-bit QuickTime Animation):
https://drive.google.com/open?id=0B3_pEBoLs0fad2s0V1YzUWo5aDA
quiz-palette+gs.mov
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2016-01-02 05:30:22 +00:00
|
|
|
/* Ignore the greyscale bit for 1-bit video and sample
|
|
|
|
* descriptions containing a color table. */
|
|
|
|
if (greyscale && bit_depth > 1 && color_table_id) {
|
2015-12-27 20:28:09 +00:00
|
|
|
int color_index, color_dec;
|
|
|
|
/* compute the greyscale palette */
|
|
|
|
color_count = 1 << bit_depth;
|
|
|
|
color_index = 255;
|
|
|
|
color_dec = 256 / (color_count - 1);
|
|
|
|
for (i = 0; i < color_count; i++) {
|
|
|
|
r = g = b = color_index;
|
|
|
|
palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
|
|
|
|
color_index -= color_dec;
|
|
|
|
if (color_index < 0)
|
|
|
|
color_index = 0;
|
|
|
|
}
|
|
|
|
} else if (color_table_id) {
|
|
|
|
/* The color table ID is non-zero. Interpret this as
|
|
|
|
* being -1, which means use the default Macintosh
|
|
|
|
* color table */
|
|
|
|
const uint8_t *color_table;
|
|
|
|
color_count = 1 << bit_depth;
|
2015-12-29 06:35:00 +00:00
|
|
|
if (bit_depth == 1)
|
|
|
|
color_table = ff_qt_default_palette_2;
|
|
|
|
else if (bit_depth == 2)
|
2015-12-27 20:28:09 +00:00
|
|
|
color_table = ff_qt_default_palette_4;
|
|
|
|
else if (bit_depth == 4)
|
|
|
|
color_table = ff_qt_default_palette_16;
|
|
|
|
else
|
|
|
|
color_table = ff_qt_default_palette_256;
|
|
|
|
for (i = 0; i < color_count; i++) {
|
|
|
|
r = color_table[i * 3 + 0];
|
|
|
|
g = color_table[i * 3 + 1];
|
|
|
|
b = color_table[i * 3 + 2];
|
|
|
|
palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* The color table ID is 0; the color table is in the sample
|
|
|
|
* description */
|
|
|
|
color_start = avio_rb32(pb);
|
|
|
|
avio_rb16(pb); /* color table flags */
|
|
|
|
color_end = avio_rb16(pb);
|
|
|
|
if ((color_start <= 255) && (color_end <= 255)) {
|
|
|
|
for (i = color_start; i <= color_end; i++) {
|
2018-04-19 18:11:02 +00:00
|
|
|
/* Each color is made of four unsigned 16 bit integers. The
|
|
|
|
* first integer is 0, the remaining integers are the red,
|
|
|
|
* the green and the blue values. We only use the top 8 bit. */
|
|
|
|
avio_skip(pb, 2);
|
2015-12-27 20:28:09 +00:00
|
|
|
r = avio_r8(pb);
|
|
|
|
avio_r8(pb);
|
|
|
|
g = avio_r8(pb);
|
|
|
|
avio_r8(pb);
|
|
|
|
b = avio_r8(pb);
|
|
|
|
avio_r8(pb);
|
2018-04-19 18:11:02 +00:00
|
|
|
palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
|
2015-12-27 20:28:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|