You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	PCX encoder that handles 1-, 8-, and 24-bpp pixfmts.
Patch by Daniel Verkamp, daniel drv nu Originally committed as revision 18077 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
				
					committed by
					
						 Carl Eugen Hoyos
						Carl Eugen Hoyos
					
				
			
			
				
	
			
			
			
						parent
						
							20ddf5a8e4
						
					
				
				
					commit
					effcedf738
				
			| @@ -5,6 +5,7 @@ version <next>: | ||||
| - deprecated old scaler removed | ||||
| - VQF demuxer | ||||
| - Alpha channel scaler | ||||
| - PCX encoder | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @@ -224,6 +224,7 @@ LAVF_TESTS = $(addprefix regtest-,              \ | ||||
|         voc                                     \ | ||||
|         ogg                                     \ | ||||
|         pixfmt                                  \ | ||||
|         pcx                                     \ | ||||
|     ) | ||||
|  | ||||
| REGFILES = $(addprefix tests/data/,$(addsuffix .$(1),$(2:regtest-%=%))) | ||||
|   | ||||
| @@ -251,7 +251,7 @@ following image formats are supported: | ||||
|     @tab PAM is a PNM extension with alpha support. | ||||
| @item PBM          @tab X @tab X | ||||
|     @tab Portable BitMap image | ||||
| @item PCX          @tab   @tab X | ||||
| @item PCX          @tab X @tab X | ||||
|     @tab PC Paintbrush | ||||
| @item PGM          @tab X @tab X | ||||
|     @tab Portable GrayMap image | ||||
|   | ||||
| @@ -159,6 +159,7 @@ OBJS-$(CONFIG_NUV_DECODER)             += nuv.o rtjpeg.o | ||||
| OBJS-$(CONFIG_PAM_ENCODER)             += pnmenc.o pnm.o | ||||
| OBJS-$(CONFIG_PBM_ENCODER)             += pnmenc.o pnm.o | ||||
| OBJS-$(CONFIG_PCX_DECODER)             += pcx.o | ||||
| OBJS-$(CONFIG_PCX_ENCODER)             += pcxenc.o | ||||
| OBJS-$(CONFIG_PGM_ENCODER)             += pnmenc.o pnm.o | ||||
| OBJS-$(CONFIG_PGMYUV_ENCODER)          += pnmenc.o pnm.o | ||||
| OBJS-$(CONFIG_PNG_DECODER)             += png.o pngdec.o | ||||
|   | ||||
| @@ -127,7 +127,7 @@ void avcodec_register_all(void) | ||||
|     REGISTER_DECODER (NUV, nuv); | ||||
|     REGISTER_ENCODER (PAM, pam); | ||||
|     REGISTER_ENCODER (PBM, pbm); | ||||
|     REGISTER_DECODER (PCX, pcx); | ||||
|     REGISTER_ENCDEC  (PCX, pcx); | ||||
|     REGISTER_ENCODER (PGM, pgm); | ||||
|     REGISTER_ENCODER (PGMYUV, pgmyuv); | ||||
|     REGISTER_ENCDEC  (PNG, png); | ||||
|   | ||||
							
								
								
									
										206
									
								
								libavcodec/pcxenc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								libavcodec/pcxenc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,206 @@ | ||||
| /* | ||||
|  * PC Paintbrush PCX (.pcx) image encoder | ||||
|  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu> | ||||
|  * | ||||
|  * 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 | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * PCX image encoder | ||||
|  * @file libavcodec/pcxenc.c | ||||
|  * @author Daniel Verkamp | ||||
|  * @sa http://www.qzx.com/pc-gpe/pcx.txt | ||||
|  */ | ||||
|  | ||||
| #include "avcodec.h" | ||||
| #include "bytestream.h" | ||||
|  | ||||
| typedef struct PCXContext { | ||||
|     AVFrame picture; | ||||
| } PCXContext; | ||||
|  | ||||
| static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF }; | ||||
|  | ||||
| static av_cold int pcx_encode_init(AVCodecContext *avctx) | ||||
| { | ||||
|     PCXContext *s = avctx->priv_data; | ||||
|  | ||||
|     avcodec_get_frame_defaults(&s->picture); | ||||
|     avctx->coded_frame = &s->picture; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * PCX run-length encoder | ||||
|  * @param dst output buffer | ||||
|  * @param dst_size size of output buffer | ||||
|  * @param src input buffer | ||||
|  * @param src_plane_size size of one plane of input buffer in bytes | ||||
|  * @param nplanes number of planes in input buffer | ||||
|  * @return number of bytes written to dst or -1 on error | ||||
|  * @bug will not work for nplanes != 1 && bpp != 8 | ||||
|  */ | ||||
| static int pcx_rle_encode(      uint8_t *dst, int dst_size, | ||||
|                           const uint8_t *src, int src_plane_size, int nplanes) | ||||
| { | ||||
|     int p; | ||||
|     const uint8_t *dst_start = dst; | ||||
|  | ||||
|     // check worst-case upper bound on dst_size | ||||
|     if (dst_size < 2LL * src_plane_size * nplanes || src_plane_size <= 0) | ||||
|         return -1; | ||||
|  | ||||
|     for (p = 0; p < nplanes; p++) { | ||||
|         int count = 1; | ||||
|         const uint8_t *src_plane = src + p; | ||||
|         const uint8_t *src_plane_end = src_plane + src_plane_size * nplanes; | ||||
|         uint8_t prev = *src_plane; | ||||
|         src_plane += nplanes; | ||||
|  | ||||
|         for (; ; src_plane += nplanes) { | ||||
|             if (src_plane < src_plane_end && *src_plane == prev && count < 0x3F) { | ||||
|                 // current byte is same as prev | ||||
|                 ++count; | ||||
|             } else { | ||||
|                 // output prev * count | ||||
|                 if (count != 1 || prev >= 0xC0) | ||||
|                     *dst++ = 0xC0 | count; | ||||
|                 *dst++ = prev; | ||||
|  | ||||
|                 if (src_plane == src_plane_end) | ||||
|                     break; | ||||
|  | ||||
|                 // start new run | ||||
|                 count = 1; | ||||
|                 prev = *src_plane; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return dst - dst_start; | ||||
| } | ||||
|  | ||||
| static int pcx_encode_frame(AVCodecContext *avctx, | ||||
|                             unsigned char *buf, int buf_size, void *data) | ||||
| { | ||||
|     PCXContext *s = avctx->priv_data; | ||||
|     AVFrame *const pict = &s->picture; | ||||
|     const uint8_t *buf_start = buf; | ||||
|     const uint8_t *buf_end   = buf + buf_size; | ||||
|  | ||||
|     int bpp, nplanes, i, y, line_bytes, written; | ||||
|     const uint32_t *pal = NULL; | ||||
|     const uint8_t *src; | ||||
|  | ||||
|     *pict = *(AVFrame *)data; | ||||
|     pict->pict_type = FF_I_TYPE; | ||||
|     pict->key_frame = 1; | ||||
|  | ||||
|     if (avctx->width > 65535 || avctx->height > 65535) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "image dimensions do not fit in 16 bits\n"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     switch (avctx->pix_fmt) { | ||||
|     case PIX_FMT_RGB24: | ||||
|         bpp = 8; | ||||
|         nplanes = 3; | ||||
|         break; | ||||
|     case PIX_FMT_RGB8: | ||||
|     case PIX_FMT_BGR8: | ||||
|     case PIX_FMT_RGB4_BYTE: | ||||
|     case PIX_FMT_BGR4_BYTE: | ||||
|     case PIX_FMT_GRAY8: | ||||
|     case PIX_FMT_PAL8: | ||||
|         bpp = 8; | ||||
|         nplanes = 1; | ||||
|         pal = (uint32_t *)pict->data[1]; | ||||
|         break; | ||||
|     case PIX_FMT_MONOBLACK: | ||||
|         bpp = 1; | ||||
|         nplanes = 1; | ||||
|         pal = monoblack_pal; | ||||
|         break; | ||||
|     default: | ||||
|         av_log(avctx, AV_LOG_ERROR, "unsupported pixfmt\n"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     line_bytes = (avctx->width * bpp + 7) >> 3; | ||||
|     line_bytes = (line_bytes + 1) & ~1; | ||||
|  | ||||
|     bytestream_put_byte(&buf, 10);                  // manufacturer | ||||
|     bytestream_put_byte(&buf, 5);                   // version | ||||
|     bytestream_put_byte(&buf, 1);                   // encoding | ||||
|     bytestream_put_byte(&buf, bpp);                 // bits per pixel per plane | ||||
|     bytestream_put_le16(&buf, 0);                   // x min | ||||
|     bytestream_put_le16(&buf, 0);                   // y min | ||||
|     bytestream_put_le16(&buf, avctx->width - 1);    // x max | ||||
|     bytestream_put_le16(&buf, avctx->height - 1);   // y max | ||||
|     bytestream_put_le16(&buf, 0);                   // horizontal DPI | ||||
|     bytestream_put_le16(&buf, 0);                   // vertical DPI | ||||
|     for (i = 0; i < 16; i++) | ||||
|         bytestream_put_be24(&buf, pal ? pal[i] : 0);// palette (<= 16 color only) | ||||
|     bytestream_put_byte(&buf, 0);                   // reserved | ||||
|     bytestream_put_byte(&buf, nplanes);             // number of planes | ||||
|     bytestream_put_le16(&buf, line_bytes);          // scanline plane size in bytes | ||||
|  | ||||
|     while (buf - buf_start < 128) | ||||
|         *buf++= 0; | ||||
|  | ||||
|     src = pict->data[0]; | ||||
|  | ||||
|     for (y = 0; y < avctx->height; y++) { | ||||
|         if ((written = pcx_rle_encode(buf, buf_end - buf, | ||||
|                                       src, line_bytes, nplanes)) < 0) { | ||||
|             av_log(avctx, AV_LOG_ERROR, "buffer too small\n"); | ||||
|             return -1; | ||||
|         } | ||||
|         buf += written; | ||||
|         src += pict->linesize[0]; | ||||
|     } | ||||
|  | ||||
|     if (nplanes == 1 && bpp == 8) { | ||||
|         if (buf_end - buf < 257) { | ||||
|             av_log(avctx, AV_LOG_ERROR, "buffer too small\n"); | ||||
|             return -1; | ||||
|         } | ||||
|         bytestream_put_byte(&buf, 12); | ||||
|         for (i = 0; i < 256; i++) { | ||||
|             bytestream_put_be24(&buf, pal[i]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return buf - buf_start; | ||||
| } | ||||
|  | ||||
| AVCodec pcx_encoder = { | ||||
|     "pcx", | ||||
|     CODEC_TYPE_VIDEO, | ||||
|     CODEC_ID_PCX, | ||||
|     sizeof(PCXContext), | ||||
|     pcx_encode_init, | ||||
|     pcx_encode_frame, | ||||
|     NULL, | ||||
|     .pix_fmts = (enum PixelFormat[]){ | ||||
|         PIX_FMT_RGB24, | ||||
|         PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, | ||||
|         PIX_FMT_MONOBLACK, | ||||
|         PIX_FMT_NONE}, | ||||
|     .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), | ||||
| }; | ||||
| @@ -428,7 +428,7 @@ AVOutputFormat image2_muxer = { | ||||
|     "image2", | ||||
|     NULL_IF_CONFIG_SMALL("image2 sequence"), | ||||
|     "", | ||||
|     "bmp,jpeg,jpg,ljpg,pam,pbm,pgm,pgmyuv,png,ppm,sgi,tif,tiff,jp2", | ||||
|     "bmp,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,ppm,sgi,tif,tiff,jp2", | ||||
|     sizeof(VideoData), | ||||
|     CODEC_ID_NONE, | ||||
|     CODEC_ID_MJPEG, | ||||
|   | ||||
| @@ -138,3 +138,6 @@ ac2c17f1a27d928e8b82f21dbafdd715 *./tests/data/b-libav-yuv440p.yuv | ||||
| 304128 ./tests/data/b-libav-yuv440p.yuv | ||||
| 10c8507ad38d0ce5e8cd0f1dd49b0d26 *./tests/data/b-libav-yuvj440p.yuv | ||||
| 304128 ./tests/data/b-libav-yuvj440p.yuv | ||||
| 574fb8fe0b2fe8cc0b3ded8549c052d4 *./tests/data/b-libav02.pcx | ||||
| ./tests/data/b-libav%02d.pcx CRC=0x6f775c0d | ||||
| 363436 ./tests/data/b-libav02.pcx | ||||
|   | ||||
| @@ -601,6 +601,10 @@ if [ -n "$do_jpg" ] ; then | ||||
| do_image_formats jpg "-flags +bitexact -dct fastint -idct simple -pix_fmt yuvj420p" "-f image2" | ||||
| fi | ||||
|  | ||||
| if [ -n "$do_pcx" ] ; then | ||||
| do_image_formats pcx | ||||
| fi | ||||
|  | ||||
| # audio only | ||||
|  | ||||
| if [ -n "$do_wav" ] ; then | ||||
|   | ||||
		Reference in New Issue
	
	Block a user