mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
lavc/pngenc: Support writing colorspace tags.
These are defined in http://www.w3.org/TR/PNG/#11addnlcolinfo.
This commit is contained in:
parent
0a23129bfc
commit
888a33c070
@ -231,6 +231,81 @@ static int png_write_row(PNGEncContext *s, const uint8_t *data, int size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define AV_WB32_PNG(buf, n) (AV_WB32(buf, round((n) * 100000)))
|
||||
static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf)
|
||||
{
|
||||
double rx, ry, gx, gy, bx, by, wx = 0.3127, wy = 0.3290;
|
||||
switch (prim) {
|
||||
case AVCOL_PRI_BT709:
|
||||
rx = 0.640; ry = 0.330;
|
||||
gx = 0.300; gy = 0.600;
|
||||
bx = 0.150; by = 0.060;
|
||||
break;
|
||||
case AVCOL_PRI_BT470M:
|
||||
rx = 0.670; ry = 0.330;
|
||||
gx = 0.210; gy = 0.710;
|
||||
bx = 0.140; by = 0.080;
|
||||
wx = 0.310; wy = 0.316;
|
||||
break;
|
||||
case AVCOL_PRI_BT470BG:
|
||||
rx = 0.640; ry = 0.330;
|
||||
gx = 0.290; gy = 0.600;
|
||||
bx = 0.150; by = 0.060;
|
||||
break;
|
||||
case AVCOL_PRI_SMPTE170M:
|
||||
case AVCOL_PRI_SMPTE240M:
|
||||
rx = 0.630; ry = 0.340;
|
||||
gx = 0.310; gy = 0.595;
|
||||
bx = 0.155; by = 0.070;
|
||||
break;
|
||||
case AVCOL_PRI_BT2020:
|
||||
rx = 0.708; ry = 0.292;
|
||||
gx = 0.170; gy = 0.797;
|
||||
bx = 0.131; by = 0.046;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
AV_WB32_PNG(buf , wx); AV_WB32_PNG(buf + 4 , wy);
|
||||
AV_WB32_PNG(buf + 8 , rx); AV_WB32_PNG(buf + 12, ry);
|
||||
AV_WB32_PNG(buf + 16, gx); AV_WB32_PNG(buf + 20, gy);
|
||||
AV_WB32_PNG(buf + 24, bx); AV_WB32_PNG(buf + 28, by);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
|
||||
{
|
||||
double gamma;
|
||||
switch (trc) {
|
||||
case AVCOL_TRC_BT709:
|
||||
case AVCOL_TRC_SMPTE170M:
|
||||
case AVCOL_TRC_SMPTE240M:
|
||||
case AVCOL_TRC_BT1361_ECG:
|
||||
case AVCOL_TRC_BT2020_10:
|
||||
case AVCOL_TRC_BT2020_12:
|
||||
/* these share a segmented TRC, but gamma 1.961 is a close
|
||||
approximation, and also more correct for decoding content */
|
||||
gamma = 1.961;
|
||||
break;
|
||||
case AVCOL_TRC_GAMMA22:
|
||||
case AVCOL_TRC_IEC61966_2_1:
|
||||
gamma = 2.2;
|
||||
break;
|
||||
case AVCOL_TRC_GAMMA28:
|
||||
gamma = 2.8;
|
||||
break;
|
||||
case AVCOL_TRC_LINEAR:
|
||||
gamma = 1.0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
AV_WB32_PNG(buf, 1.0 / gamma);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
const AVFrame *pict, int *got_packet)
|
||||
{
|
||||
@ -358,6 +433,18 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
}
|
||||
png_write_chunk(&s->bytestream, MKTAG('p', 'H', 'Y', 's'), s->buf, 9);
|
||||
|
||||
/* write colorspace information */
|
||||
if (pict->color_primaries == AVCOL_PRI_BT709 &&
|
||||
pict->color_trc == AVCOL_TRC_IEC61966_2_1) {
|
||||
s->buf[0] = 1; /* rendering intent, relative colorimetric by default */
|
||||
png_write_chunk(&s->bytestream, MKTAG('s', 'R', 'G', 'B'), s->buf, 1);
|
||||
}
|
||||
|
||||
if (png_get_chrm(pict->color_primaries, s->buf))
|
||||
png_write_chunk(&s->bytestream, MKTAG('c', 'H', 'R', 'M'), s->buf, 32);
|
||||
if (png_get_gama(pict->color_trc, s->buf))
|
||||
png_write_chunk(&s->bytestream, MKTAG('g', 'A', 'M', 'A'), s->buf, 4);
|
||||
|
||||
/* put the palette if needed */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
int has_alpha, alpha, i;
|
||||
|
Loading…
x
Reference in New Issue
Block a user