00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023 #include "internal.h"
00024 #include "pnm.h"
00025
00026
00027 static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00028 const AVFrame *pict, int *got_packet)
00029 {
00030 PNMContext *s = avctx->priv_data;
00031 AVFrame * const p = &s->picture;
00032 int i, h, w, n, linesize, depth, maxval, ret;
00033 const char *tuple_type;
00034 uint8_t *ptr;
00035
00036 h = avctx->height;
00037 w = avctx->width;
00038 switch (avctx->pix_fmt) {
00039 case PIX_FMT_MONOBLACK:
00040 n = w;
00041 depth = 1;
00042 maxval = 1;
00043 tuple_type = "BLACKANDWHITE";
00044 break;
00045 case PIX_FMT_GRAY8:
00046 n = w;
00047 depth = 1;
00048 maxval = 255;
00049 tuple_type = "GRAYSCALE";
00050 break;
00051 case PIX_FMT_GRAY16BE:
00052 n = w * 2;
00053 depth = 1;
00054 maxval = 0xFFFF;
00055 tuple_type = "GRAYSCALE";
00056 break;
00057 case PIX_FMT_GRAY8A:
00058 n = w * 2;
00059 depth = 2;
00060 maxval = 255;
00061 tuple_type = "GRAYSCALE_ALPHA";
00062 break;
00063 case PIX_FMT_RGB24:
00064 n = w * 3;
00065 depth = 3;
00066 maxval = 255;
00067 tuple_type = "RGB";
00068 break;
00069 case PIX_FMT_RGBA:
00070 n = w * 4;
00071 depth = 4;
00072 maxval = 255;
00073 tuple_type = "RGB_ALPHA";
00074 break;
00075 case PIX_FMT_RGB48BE:
00076 n = w * 6;
00077 depth = 3;
00078 maxval = 0xFFFF;
00079 tuple_type = "RGB";
00080 break;
00081 case PIX_FMT_RGBA64BE:
00082 n = w * 8;
00083 depth = 4;
00084 maxval = 0xFFFF;
00085 tuple_type = "RGB_ALPHA";
00086 break;
00087 default:
00088 return -1;
00089 }
00090
00091 if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200)) < 0)
00092 return ret;
00093
00094 *p = *pict;
00095 p->pict_type = AV_PICTURE_TYPE_I;
00096 p->key_frame = 1;
00097
00098 s->bytestream_start =
00099 s->bytestream = pkt->data;
00100 s->bytestream_end = pkt->data + pkt->size;
00101
00102 snprintf(s->bytestream, s->bytestream_end - s->bytestream,
00103 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
00104 w, h, depth, maxval, tuple_type);
00105 s->bytestream += strlen(s->bytestream);
00106
00107 ptr = p->data[0];
00108 linesize = p->linesize[0];
00109
00110 if (avctx->pix_fmt == PIX_FMT_MONOBLACK){
00111 int j;
00112 for (i = 0; i < h; i++) {
00113 for (j = 0; j < w; j++)
00114 *s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
00115 ptr += linesize;
00116 }
00117 } else {
00118 for (i = 0; i < h; i++) {
00119 memcpy(s->bytestream, ptr, n);
00120 s->bytestream += n;
00121 ptr += linesize;
00122 }
00123 }
00124
00125 pkt->size = s->bytestream - s->bytestream_start;
00126 pkt->flags |= AV_PKT_FLAG_KEY;
00127 *got_packet = 1;
00128 return 0;
00129 }
00130
00131
00132 AVCodec ff_pam_encoder = {
00133 .name = "pam",
00134 .type = AVMEDIA_TYPE_VIDEO,
00135 .id = CODEC_ID_PAM,
00136 .priv_data_size = sizeof(PNMContext),
00137 .init = ff_pnm_init,
00138 .encode2 = pam_encode_frame,
00139 .pix_fmts = (const enum PixelFormat[]){
00140 PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_RGB48BE, PIX_FMT_RGBA64BE, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16BE, PIX_FMT_MONOBLACK, PIX_FMT_NONE
00141 },
00142 .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
00143 };