Libav
|
00001 /* 00002 * PAM image format 00003 * Copyright (c) 2002, 2003 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "avcodec.h" 00023 #include "bytestream.h" 00024 #include "pnm.h" 00025 00026 00027 static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, 00028 int buf_size, void *data) 00029 { 00030 PNMContext *s = avctx->priv_data; 00031 AVFrame *pict = data; 00032 AVFrame * const p = (AVFrame*)&s->picture; 00033 int i, h, w, n, linesize, depth, maxval; 00034 const char *tuple_type; 00035 uint8_t *ptr; 00036 00037 if (buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200) { 00038 av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); 00039 return -1; 00040 } 00041 00042 *p = *pict; 00043 p->pict_type = FF_I_TYPE; 00044 p->key_frame = 1; 00045 00046 s->bytestream_start = 00047 s->bytestream = outbuf; 00048 s->bytestream_end = outbuf+buf_size; 00049 00050 h = avctx->height; 00051 w = avctx->width; 00052 switch (avctx->pix_fmt) { 00053 case PIX_FMT_MONOWHITE: 00054 n = (w + 7) >> 3; 00055 depth = 1; 00056 maxval = 1; 00057 tuple_type = "BLACKANDWHITE"; 00058 break; 00059 case PIX_FMT_GRAY8: 00060 n = w; 00061 depth = 1; 00062 maxval = 255; 00063 tuple_type = "GRAYSCALE"; 00064 break; 00065 case PIX_FMT_RGB24: 00066 n = w * 3; 00067 depth = 3; 00068 maxval = 255; 00069 tuple_type = "RGB"; 00070 break; 00071 case PIX_FMT_RGB32: 00072 n = w * 4; 00073 depth = 4; 00074 maxval = 255; 00075 tuple_type = "RGB_ALPHA"; 00076 break; 00077 default: 00078 return -1; 00079 } 00080 snprintf(s->bytestream, s->bytestream_end - s->bytestream, 00081 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n", 00082 w, h, depth, maxval, tuple_type); 00083 s->bytestream += strlen(s->bytestream); 00084 00085 ptr = p->data[0]; 00086 linesize = p->linesize[0]; 00087 00088 if (avctx->pix_fmt == PIX_FMT_RGB32) { 00089 int j; 00090 unsigned int v; 00091 00092 for (i = 0; i < h; i++) { 00093 for (j = 0; j < w; j++) { 00094 v = ((uint32_t *)ptr)[j]; 00095 bytestream_put_be24(&s->bytestream, v); 00096 *s->bytestream++ = v >> 24; 00097 } 00098 ptr += linesize; 00099 } 00100 } else { 00101 for (i = 0; i < h; i++) { 00102 memcpy(s->bytestream, ptr, n); 00103 s->bytestream += n; 00104 ptr += linesize; 00105 } 00106 } 00107 return s->bytestream - s->bytestream_start; 00108 } 00109 00110 00111 AVCodec pam_encoder = { 00112 "pam", 00113 AVMEDIA_TYPE_VIDEO, 00114 CODEC_ID_PAM, 00115 sizeof(PNMContext), 00116 ff_pnm_init, 00117 pam_encode_frame, 00118 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE}, 00119 .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), 00120 };