diff options
author | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2009-10-27 20:56:56 +0000 |
---|---|---|
committer | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2009-10-27 20:56:56 +0000 |
commit | 51135d1d8e113aef5dbafd578460daeb92972c7f (patch) | |
tree | dce6c8209f8ddeeb587cd81d008b2b077f232839 /libavutil | |
parent | 04a5c106f902ee04a02109e1e7f6b1fa7794eb4e (diff) | |
download | ffmpeg-51135d1d8e113aef5dbafd578460daeb92972c7f.tar.gz |
Move pixdesc.{h,c} from libavcodec to libavutil.
This way pixdescs can be used without requiring a dependency on
libavcodec.
Originally committed as revision 20389 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/pixdesc.c | 596 | ||||
-rw-r--r-- | libavutil/pixdesc.h | 207 |
2 files changed, 803 insertions, 0 deletions
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c new file mode 100644 index 0000000000..7e8cea76c6 --- /dev/null +++ b/libavutil/pixdesc.c @@ -0,0 +1,596 @@ +/* + * pixel format descriptor + * 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 + */ + +#include "pixfmt.h" +#include "pixdesc.h" + +const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = { + [PIX_FMT_YUV420P] = { + .name = "yuv420p", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUYV422] = { + .name = "yuyv422", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,7}, /* Y */ + {0,3,2,0,7}, /* U */ + {0,3,4,0,7}, /* V */ + }, + }, + [PIX_FMT_RGB24] = { + .name = "rgb24", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,2,1,0,7}, /* R */ + {0,2,2,0,7}, /* G */ + {0,2,3,0,7}, /* B */ + }, + }, + [PIX_FMT_BGR24] = { + .name = "bgr24", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,2,1,0,7}, /* B */ + {0,2,2,0,7}, /* G */ + {0,2,3,0,7}, /* R */ + }, + }, + [PIX_FMT_YUV422P] = { + .name = "yuv422p", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUV444P] = { + .name = "yuv444p", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUV410P] = { + .name = "yuv410p", + .nb_channels = 3, + .log2_chroma_w= 2, + .log2_chroma_h= 2, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUV411P] = { + .name = "yuv411p", + .nb_channels = 3, + .log2_chroma_w= 2, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_GRAY8] = { + .name = "gray8", + .nb_channels = 1, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, /* Y */ + }, + }, + [PIX_FMT_MONOWHITE] = { + .name = "monowhite", + .nb_channels = 1, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,0}, /* Y */ + }, + .flags = PIX_FMT_BITSTREAM, + }, + [PIX_FMT_MONOBLACK] = { + .name = "monoblack", + .nb_channels = 1, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,7,0}, /* Y */ + }, + .flags = PIX_FMT_BITSTREAM, + }, + [PIX_FMT_PAL8] = { + .name = "pal8", + .nb_channels = 1, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, + }, + .flags = PIX_FMT_PAL, + }, + [PIX_FMT_YUVJ420P] = { + .name = "yuvj420p", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUVJ422P] = { + .name = "yuvj422p", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUVJ444P] = { + .name = "yuvj444p", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_UYVY422] = { + .name = "uyvy422", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 0, + .comp = { + {0,1,2,0,7}, /* Y */ + {0,3,1,0,7}, /* U */ + {0,3,3,0,7}, /* V */ + }, + }, + [PIX_FMT_UYYVYY411] = { + .name = "uyyvyy411", + .nb_channels = 3, + .log2_chroma_w= 2, + .log2_chroma_h= 0, + .comp = { + {0,3,2,0,7}, /* Y */ + {0,5,1,0,7}, /* U */ + {0,5,4,0,7}, /* V */ + }, + }, + [PIX_FMT_BGR8] = { + .name = "bgr8", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,6,1}, /* B */ + {0,0,1,3,2}, /* G */ + {0,0,1,0,2}, /* R */ + }, + }, + [PIX_FMT_BGR4] = { + .name = "bgr4", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,3,1,0,0}, /* B */ + {0,3,2,0,1}, /* G */ + {0,3,4,0,0}, /* R */ + }, + .flags = PIX_FMT_BITSTREAM, + }, + [PIX_FMT_BGR4_BYTE] = { + .name = "bgr4_byte", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,3,0}, /* B */ + {0,0,1,1,1}, /* G */ + {0,0,1,0,0}, /* R */ + }, + }, + [PIX_FMT_RGB8] = { + .name = "rgb8", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,6,1}, /* R */ + {0,0,1,3,2}, /* G */ + {0,0,1,0,2}, /* B */ + }, + }, + [PIX_FMT_RGB4] = { + .name = "rgb4", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,3,1,0,0}, /* R */ + {0,3,2,0,1}, /* G */ + {0,3,4,0,0}, /* B */ + }, + .flags = PIX_FMT_BITSTREAM, + }, + [PIX_FMT_RGB4_BYTE] = { + .name = "rgb4_byte", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,0,1,3,0}, /* R */ + {0,0,1,1,1}, /* G */ + {0,0,1,0,0}, /* B */ + }, + }, + [PIX_FMT_NV12] = { + .name = "nv12", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,1,1,0,7}, /* U */ + {1,1,2,0,7}, /* V */ + }, + }, + [PIX_FMT_NV21] = { + .name = "nv21", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,1,1,0,7}, /* V */ + {1,1,2,0,7}, /* U */ + }, + }, + [PIX_FMT_ARGB] = { + .name = "argb", + .nb_channels = 4, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,3,1,0,7}, /* A */ + {0,3,2,0,7}, /* R */ + {0,3,3,0,7}, /* G */ + {0,3,4,0,7}, /* B */ + }, + }, + [PIX_FMT_RGBA] = { + .name = "rgba", + .nb_channels = 4, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,3,1,0,7}, /* R */ + {0,3,2,0,7}, /* G */ + {0,3,3,0,7}, /* B */ + {0,3,4,0,7}, /* A */ + }, + }, + [PIX_FMT_ABGR] = { + .name = "abgr", + .nb_channels = 4, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,3,1,0,7}, /* A */ + {0,3,2,0,7}, /* B */ + {0,3,3,0,7}, /* G */ + {0,3,4,0,7}, /* R */ + }, + }, + [PIX_FMT_BGRA] = { + .name = "bgra", + .nb_channels = 4, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,3,1,0,7}, /* B */ + {0,3,2,0,7}, /* G */ + {0,3,3,0,7}, /* R */ + {0,3,4,0,7}, /* A */ + }, + }, + [PIX_FMT_GRAY16BE] = { + .name = "gray16be", + .nb_channels = 1, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,15}, /* Y */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_GRAY16LE] = { + .name = "gray16le", + .nb_channels = 1, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,15}, /* Y */ + }, + }, + [PIX_FMT_YUV440P] = { + .name = "yuv440p", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUVJ440P] = { + .name = "yuvj440p", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + }, + }, + [PIX_FMT_YUVA420P] = { + .name = "yuva420p", + .nb_channels = 4, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,0,1,0,7}, /* Y */ + {1,0,1,0,7}, /* U */ + {2,0,1,0,7}, /* V */ + {3,0,1,0,7}, /* A */ + }, + }, + [PIX_FMT_RGB48BE] = { + .name = "rgb48be", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,5,1,0,15}, /* R */ + {0,5,3,0,15}, /* G */ + {0,5,5,0,15}, /* B */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_RGB48LE] = { + .name = "rgb48le", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,5,1,0,15}, /* R */ + {0,5,3,0,15}, /* G */ + {0,5,5,0,15}, /* B */ + }, + }, + [PIX_FMT_RGB565BE] = { + .name = "rgb565be", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,0,3,4}, /* R */ + {0,1,1,5,5}, /* G */ + {0,1,1,0,4}, /* B */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_RGB565LE] = { + .name = "rgb565le", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,2,3,4}, /* R */ + {0,1,1,5,5}, /* G */ + {0,1,1,0,4}, /* B */ + }, + }, + [PIX_FMT_RGB555BE] = { + .name = "rgb555be", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,0,2,4}, /* R */ + {0,1,1,5,4}, /* G */ + {0,1,1,0,4}, /* B */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_RGB555LE] = { + .name = "rgb555le", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,2,2,4}, /* R */ + {0,1,1,5,4}, /* G */ + {0,1,1,0,4}, /* B */ + }, + }, + [PIX_FMT_BGR565BE] = { + .name = "bgr565be", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,0,3,4}, /* B */ + {0,1,1,5,5}, /* G */ + {0,1,1,0,4}, /* R */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_BGR565LE] = { + .name = "bgr565le", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,2,3,4}, /* B */ + {0,1,1,5,5}, /* G */ + {0,1,1,0,4}, /* R */ + }, + }, + [PIX_FMT_BGR555BE] = { + .name = "bgr555be", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,0,2,4}, /* B */ + {0,1,1,5,4}, /* G */ + {0,1,1,0,4}, /* R */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_BGR555LE] = { + .name = "bgr555le", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,2,2,4}, /* B */ + {0,1,1,5,4}, /* G */ + {0,1,1,0,4}, /* R */ + }, + }, + [PIX_FMT_YUV420P16LE] = { + .name = "yuv420p16le", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,1,1,0,15}, /* Y */ + {1,1,1,0,15}, /* U */ + {2,1,1,0,15}, /* V */ + }, + }, + [PIX_FMT_YUV420P16BE] = { + .name = "yuv420p16be", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 1, + .comp = { + {0,1,1,0,15}, /* Y */ + {1,1,1,0,15}, /* U */ + {2,1,1,0,15}, /* V */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_YUV422P16LE] = { + .name = "yuv422p16le", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,15}, /* Y */ + {1,1,1,0,15}, /* U */ + {2,1,1,0,15}, /* V */ + }, + }, + [PIX_FMT_YUV422P16BE] = { + .name = "yuv422p16be", + .nb_channels = 3, + .log2_chroma_w= 1, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,15}, /* Y */ + {1,1,1,0,15}, /* U */ + {2,1,1,0,15}, /* V */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_YUV444P16LE] = { + .name = "yuv444p16le", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,15}, /* Y */ + {1,1,1,0,15}, /* U */ + {2,1,1,0,15}, /* V */ + }, + }, + [PIX_FMT_YUV444P16BE] = { + .name = "yuv444p16be", + .nb_channels = 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,15}, /* Y */ + {1,1,1,0,15}, /* U */ + {2,1,1,0,15}, /* V */ + }, + .flags = PIX_FMT_BE, + }, +}; + +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc) +{ + int c, bits = 0; + int log2_pixels = pixdesc->log2_chroma_w + pixdesc->log2_chroma_h; + + for (c = 0; c < pixdesc->nb_channels; c++) { + int s = c==1 || c==2 ? 0 : log2_pixels; + bits += (pixdesc->comp[c].depth_minus1+1) << s; + } + + return bits >> log2_pixels; +} diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h new file mode 100644 index 0000000000..fd1428fd81 --- /dev/null +++ b/libavutil/pixdesc.h @@ -0,0 +1,207 @@ +/* + * pixel format descriptor + * 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 + */ + +#ifndef AVUTIL_PIXDESC_H +#define AVUTIL_PIXDESC_H + +#include <inttypes.h> + +#include "intreadwrite.h" + +typedef struct AVComponentDescriptor{ + uint16_t plane :2; ///< which of the 4 planes contains the component + + /** + * 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; + uint16_t shift :3; ///< number of least significant bits that must be shifted away to get the value + uint16_t depth_minus1 :4; ///< number of bits in the component minus 1 +}AVComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @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. + */ +typedef struct AVPixFmtDescriptor{ + const char *name; + uint8_t nb_channels; ///< The number of components each pixel has, (1-4) + + /** + * 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. + */ + uint8_t log2_chroma_w; ///< chroma_width = -((-luma_width )>>log2_chroma_w) + + /** + * 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. + */ + uint8_t log2_chroma_h; + uint8_t flags; + AVComponentDescriptor comp[4]; ///< parameters that describe how pixels are packed +}AVPixFmtDescriptor; + +#define PIX_FMT_BE 1 ///< big-endian +#define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette. +#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end. +#define PIX_FMT_HWACCEL 8 ///< Pixel format is an HW accelerated format. + +/** + * The array of all the pixel format descriptors. + */ +extern const AVPixFmtDescriptor av_pix_fmt_descriptors[]; + +/** + * Reads a line from an image, and writes to dst the values of the + * pixel format component c. + * + * @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 + * values to write to dst + * @param read_pal_component if not zero and the format is a paletted + * format writes to dst the values corresponding to the palette + * component c in data[1], rather than the palette indexes in + * data[0]. The behavior is undefined if the format is not paletted. + */ +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) +{ + 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; + + if (flags & PIX_FMT_BITSTREAM){ + 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); + + while(w--){ + int val = (*p >> shift) & mask; + if(read_pal_component) + val= data[1][4*val + c]; + shift -= step; + p -= shift>>3; + shift &= 7; + *dst++= val; + } + } else { + const uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1; + + while(w--){ + int val; + if(flags & PIX_FMT_BE) val= AV_RB16(p); + else val= AV_RL16(p); + val = (val>>shift) & mask; + if(read_pal_component) + val= data[1][4*val + c]; + p+= step; + *dst++= val; + } + } +} + +/** + * 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; + } + } +} + +/** + * 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); + +#endif /* AVUTIL_PIXDESC_H */ |