pixdesc.h 7.4 KB
Newer Older
1
/*
2
 * pixel format descriptor
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
 *
 * 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
 */

22 23 24
#ifndef AVCODEC_PIXDESC_H
#define AVCODEC_PIXDESC_H

25 26 27 28 29 30
#include <inttypes.h>

#include "libavutil/intreadwrite.h"

typedef struct AVComponentDescriptor{
    uint16_t plane        :2;            ///< which of the 4 planes contains the component
31 32 33 34 35 36 37 38 39 40 41 42

    /**
     * Number of elements between 2 horizontally consecutive pixels minus 1.
     * Elements are bits for bitstream formats, bytes otherwise.
     */
    uint16_t step_minus1  :3;

    /**
     * Number of elements before the component of the first pixel plus 1.
     * Elements are bits for bitstream formats, bytes otherwise.
     */
    uint16_t offset_plus1 :3;
43
    uint16_t shift        :3;            ///< number of least significant bits that must be shifted away to get the value
44 45 46
    uint16_t depth_minus1 :4;            ///< number of bits in the component minus 1
}AVComponentDescriptor;

Michael Niedermayer's avatar
Michael Niedermayer committed
47
/**
48
 * Descriptor that unambiguously describes how the bits of a pixel are
Michael Niedermayer's avatar
Michael Niedermayer committed
49 50 51
 * stored in the up to 4 data planes of an image. It also stores the
 * subsampling factors and number of components.
 *
52 53 54
 * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV
 *       and all the YUV variants) AVPixFmtDescriptor just stores how values
 *       are stored not what these values represent.
Michael Niedermayer's avatar
Michael Niedermayer committed
55
 */
56
typedef struct AVPixFmtDescriptor{
57
    const char *name;
58 59 60
    uint8_t nb_channels;        ///< The number of components each pixel has, (1-4)

    /**
61 62 63 64
     * Amount to shift the luma width right to find the chroma width.
     * For YV12 this is 1 for example.
     * chroma_width = -((-luma_width) >> log2_chroma_w)
     * The note above is needed to ensure rounding up.
65 66 67 68
     */
    uint8_t log2_chroma_w;      ///< chroma_width = -((-luma_width )>>log2_chroma_w)

    /**
69 70 71 72
     * Amount to shift the luma height right to find the chroma height.
     * For YV12 this is 1 for example.
     * chroma_height= -((-luma_height) >> log2_chroma_h)
     * The note above is needed to ensure rounding up.
73 74 75
     */
    uint8_t log2_chroma_h;
    uint8_t flags;
76
    AVComponentDescriptor comp[4]; ///< parameters that describe how pixels are packed
77 78
}AVPixFmtDescriptor;

79
#define PIX_FMT_BE        1 ///< big-endian
Stefano Sabatini's avatar
Stefano Sabatini committed
80
#define PIX_FMT_PAL       2 ///< Pixel format has a palette in data[1], values are indexes in this palette.
81
#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end.
82

83 84 85 86
/**
 * The array of all the pixel format descriptors.
 */
extern const AVPixFmtDescriptor av_pix_fmt_descriptors[];
87

Stefano Sabatini's avatar
Stefano Sabatini committed
88
/**
89 90
 * Reads a line from an image, and writes to dst the values of the
 * pixel format component c.
Stefano Sabatini's avatar
Stefano Sabatini committed
91 92 93 94 95 96 97
 *
 * @param data the array containing the pointers to the planes of the image
 * @param linesizes the array containing the linesizes of the image
 * @param desc the pixel format descriptor for the image
 * @param x the horizontal coordinate of the first pixel to read
 * @param y the vertical coordinate of the first pixel to read
 * @param w the width of the line to read, that is the number of
98
 * values to write to dst
99
 * @param read_pal_component if not zero and the format is a paletted
100 101
 * format writes to dst the values corresponding to the palette
 * component c in data[1], rather than the palette indexes in
102
 * data[0]. The behavior is undefined if the format is not paletted.
Stefano Sabatini's avatar
Stefano Sabatini committed
103
 */
104 105
static inline void read_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4],
                             const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component)
106 107 108 109 110 111 112 113 114
{
    AVComponentDescriptor comp= desc->comp[c];
    int plane= comp.plane;
    int depth= comp.depth_minus1+1;
    int mask = (1<<depth)-1;
    int shift= comp.shift;
    int step = comp.step_minus1+1;
    int flags= desc->flags;

115
    if (flags & PIX_FMT_BITSTREAM){
116 117 118
        int skip = x*step + comp.offset_plus1-1;
        const uint8_t *p = data[plane] + y*linesize[plane] + (skip>>3);
        int shift = 8 - depth - (skip&7);
119 120

        while(w--){
121
            int val = (*p >> shift) & mask;
122
            if(read_pal_component)
123
                val= data[1][4*val + c];
124 125 126
            shift -= step;
            p -= shift>>3;
            shift &= 7;
127 128 129
            *dst++= val;
        }
    } else {
130
        const uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1;
131

132 133 134 135 136
        while(w--){
            int val;
            if(flags & PIX_FMT_BE) val= AV_RB16(p);
            else                   val= AV_RL16(p);
            val = (val>>shift) & mask;
137
            if(read_pal_component)
138
                val= data[1][4*val + c];
139
            p+= step;
140 141
            *dst++= val;
        }
142
    }
143
}
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

/**
 * Writes the values from src to the pixel format component c of an
 * image line.
 *
 * @param src array containing the values to write
 * @param data the array containing the pointers to the planes of the
 * image to write into. It is supposed to be zeroed.
 * @param linesizes the array containing the linesizes of the image
 * @param desc the pixel format descriptor for the image
 * @param x the horizontal coordinate of the first pixel to write
 * @param y the vertical coordinate of the first pixel to write
 * @param w the width of the line to write, that is the number of
 * values to write to the image line
 */
static inline void write_line(const uint16_t *src, uint8_t *data[4], const int linesize[4],
                              const AVPixFmtDescriptor *desc, int x, int y, int c, int w)
{
    AVComponentDescriptor comp = desc->comp[c];
    int plane = comp.plane;
    int depth = comp.depth_minus1+1;
    int step  = comp.step_minus1+1;
    int flags = desc->flags;

    if (flags & PIX_FMT_BITSTREAM) {
        int skip = x*step + comp.offset_plus1-1;
        uint8_t *p = data[plane] + y*linesize[plane] + (skip>>3);
        int shift = 8 - depth - (skip&7);

        while (w--) {
            *p |= *src++ << shift;
            shift -= step;
            p -= shift>>3;
            shift &= 7;
        }
    } else {
        int shift = comp.shift;
        uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1;

        while (w--) {
            if (flags & PIX_FMT_BE) {
                uint16_t val = AV_RB16(p) | (*src++<<shift);
                AV_WB16(p, val);
            } else {
                uint16_t val = AV_RL16(p) | (*src++<<shift);
                AV_WL16(p, val);
            }
            p+= step;
        }
    }
}
195

196 197 198 199 200 201 202 203 204 205
/**
 * Returns the number of bits per pixel used by the pixel format
 * described by pixdesc.
 *
 * The returned number of bits refers to the number of bits actually
 * used for storing the pixel information, that is padding bits are
 * not counted.
 */
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc);

206
#endif /* AVCODEC_PIXDESC_H */