⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpeg_enc.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Straightforward (to be) optimized JPEG encoder for the YUV422 format  * based on mjpeg code from ffmpeg.  * * Copyright (c) 2002, Rik Snel * Parts from ffmpeg Copyright (c) 2000-2002 Fabrice Bellard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * For an excellent introduction to the JPEG format, see: * http://www.ece.purdue.edu/~bouman/grad-labs/lab8/pdf/lab.pdf */#include <sys/types.h>#include <mplaylib.h>#include <mplaylib.h>#include "config.h"#include "mp_msg.h"/* We need this #define because we need ../libavcodec/common.h to #define  * be2me_32, otherwise the linker will complain that it doesn't exist */#define HAVE_AV_CONFIG_H#include "libavcodec/avcodec.h"#include "libavcodec/dsputil.h"#include "libavcodec/mpegvideo.h"#include "jpeg_enc.h"extern int avcodec_inited;/* zr_mjpeg_encode_mb needs access to these tables for the black & white  * option */typedef struct MJpegContext {    uint8_t huff_size_dc_luminance[12];    uint16_t huff_code_dc_luminance[12];    uint8_t huff_size_dc_chrominance[12];    uint16_t huff_code_dc_chrominance[12];    uint8_t huff_size_ac_luminance[256];    uint16_t huff_code_ac_luminance[256];    uint8_t huff_size_ac_chrominance[256];    uint16_t huff_code_ac_chrominance[256];} MJpegContext;/* Begin excessive code duplication ************************************//* Code coming from mpegvideo.c and mjpeg.c in ../libavcodec ***********/static const unsigned short aanscales[64] = {    /* precomputed values scaled up by 14 bits */    16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,    22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,    21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,    19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,    16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,    12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,    8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,    4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247};static void convert_matrix(MpegEncContext *s, int (*qmat)[64], 		uint16_t (*qmat16)[2][64], const uint16_t *quant_matrix,		int bias, int qmin, int qmax){    int qscale;    for(qscale=qmin; qscale<=qmax; qscale++){        int i;	if (s->dsp.fdct == ff_jpeg_fdct_islow) {		for (i = 0; i < 64; i++) {			const int j = s->dsp.idct_permutation[i];			/* 16    <= qscale * quant_matrix[i] <= 7905 			 * 19952 <= aanscales[i] *  \			 * 	        qscale * quant_matrix[i]     <= 205026 			 * (1<<36)/19952 >= (1<<36)/(aanscales[i] * \			 * 	qscale * quant_matrix[i]) >= (1<<36)/249205025			 * 3444240       >= (1<<36)/(aanscales[i] *			 *      qscale * quant_matrix[i]) >= 275              */			qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT-3))/					(qscale * quant_matrix[j]));		}	} else if (s->dsp.fdct == fdct_ifast) {            for(i=0;i<64;i++) {                const int j = s->dsp.idct_permutation[i];                /* 16 <= qscale * quant_matrix[i] <= 7905 */                /* 19952         <= aanscales[i] * qscale * quant_matrix[i]           <= 249205026 */                /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */                /* 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */                                qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) /                                 (aanscales[i] * qscale * quant_matrix[j]));            }        } else {            for(i=0;i<64;i++) {		const int j = s->dsp.idct_permutation[i];                /* We can safely suppose that 16 <= quant_matrix[i] <= 255                   So 16           <= qscale * quant_matrix[i]             <= 7905                   so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905                   so 32768        >= (1<<19) / (qscale * quant_matrix[i]) >= 67                */                qmat  [qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]));                qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);                if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1;                qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]);            }        }    }}static inline void encode_dc(MpegEncContext *s, int val,                              uint8_t *huff_size, uint16_t *huff_code){    int mant, nbits;    if (val == 0) {        put_bits(&s->pb, huff_size[0], huff_code[0]);    } else {        mant = val;        if (val < 0) {            val = -val;            mant--;        }                /* compute the log (XXX: optimize) */        nbits = 0;        while (val != 0) {            val = val >> 1;            nbits++;        }                    put_bits(&s->pb, huff_size[nbits], huff_code[nbits]);                put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));    }}static void encode_block(MpegEncContext *s, DCTELEM *block, int n){    int mant, nbits, code, i, j;    int component, dc, run, last_index, val;    MJpegContext *m = s->mjpeg_ctx;    uint8_t *huff_size_ac;    uint16_t *huff_code_ac;        /* DC coef */    component = (n <= 3 ? 0 : n - 4 + 1);    dc = block[0]; /* overflow is impossible */    val = dc - s->last_dc[component];    if (n < 4) {        encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);        huff_size_ac = m->huff_size_ac_luminance;        huff_code_ac = m->huff_code_ac_luminance;    } else {        encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);        huff_size_ac = m->huff_size_ac_chrominance;        huff_code_ac = m->huff_code_ac_chrominance;    }    s->last_dc[component] = dc;        /* AC coefs */        run = 0;    last_index = s->block_last_index[n];    for(i=1;i<=last_index;i++) {        j = s->intra_scantable.permutated[i];        val = block[j];        if (val == 0) {            run++;        } else {            while (run >= 16) {                put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]);                run -= 16;            }            mant = val;            if (val < 0) {                val = -val;                mant--;            }                        /* compute the log (XXX: optimize) */            nbits = 0;            while (val != 0) {                val = val >> 1;                nbits++;            }            code = (run << 4) | nbits;            put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]);                    put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));            run = 0;        }    }    /* output EOB only if not already 64 values */    if (last_index < 63 || run != 0)        put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);}static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index){    int i;    const int maxlevel= s->max_qcoeff;    const int minlevel= s->min_qcoeff;    for(i=0; i<=last_index; i++){        const int j = s->intra_scantable.permutated[i];        int level = block[j];               if     (level>maxlevel) level=maxlevel;        else if(level<minlevel) level=minlevel;        block[j]= level;    }}/* End excessive code duplication **************************************//* this function is a reproduction of the one in mjpeg, it includes two * changes, it allows for black&white encoding (it skips the U and V * macroblocks and it outputs the huffman code for 'no change' (dc) and * 'all zero' (ac)) and it takes 4 macroblocks (422) instead of 6 (420) */static void zr_mjpeg_encode_mb(jpeg_enc_t *j) {	MJpegContext *m = j->s->mjpeg_ctx;	encode_block(j->s, j->s->block[0], 0);	encode_block(j->s, j->s->block[1], 1);	if (j->bw) {		/* U */		put_bits(&j->s->pb, m->huff_size_dc_chrominance[0],				m->huff_code_dc_chrominance[0]);		put_bits(&j->s->pb, m->huff_size_ac_chrominance[0],				m->huff_code_ac_chrominance[0]);		/* V */		put_bits(&j->s->pb, m->huff_size_dc_chrominance[0],				m->huff_code_dc_chrominance[0]);		put_bits(&j->s->pb, m->huff_size_ac_chrominance[0],				m->huff_code_ac_chrominance[0]);    	} else {		/* we trick encode_block here so that it uses		 * chrominance huffman tables instead of luminance ones 		 * (see the effect of second argument of encode_block) */		encode_block(j->s, j->s->block[2], 4); 		encode_block(j->s, j->s->block[3], 5);    	}}/* this function can take all kinds of YUV colorspaces * YV12, YVYU, UYVY. The necesary parameters must be set up by the caller * y_ps means "y pixel size", y_rs means "y row size". * For YUYV, for example, is u_buf = y_buf + 1, v_buf = y_buf + 3,  * y_ps = 2, u_ps = 4, v_ps = 4, y_rs = u_rs = v_rs.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -