?? utils.c
字號:
/****************************************************************************# Spcaview: Spca5xx Grabber ## Copyright (C) 2004 2005 Michel Xhaard ## ## 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## #****************************************************************************/#include "utils.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <linux/types.h>#include <string.h>#include <fcntl.h>#include <wait.h>#include <time.h>#include <limits.h>#include "jdatatype.h"#include "encoder.h"#include <linux/videodev.h>#include "jconfig.h"doublems_time (void);staticswapRB (char *Buffer, int size);void exit_fatal(char *messages){ printf("%s \n",messages); exit(1);}doublems_time (void){ static struct timeval tod; gettimeofday (&tod, NULL); return ((double) tod.tv_sec * 1000.0 + (double) tod.tv_usec / 1000.0);}staticswapRB (char *Buffer, int size){ char temp; int i; for (i = 0; i < size; i += 3) { temp = Buffer[i]; Buffer[i] = Buffer[i + 2]; Buffer[i + 2] = temp; }}#define CLIP(color) (unsigned char)((color>0xFF)?0xff:((color<0)?0:color))voidYUV420toRGB (unsigned char *src, unsigned char *dst, int width, int height, int flipUV, int ColSpace){ unsigned char *Y; unsigned char *V; unsigned char *U; int y1, y2, u, v; int v1, v2, u1, u2; unsigned char *pty1, *pty2; int i, j; unsigned char *RGB1, *RGB2; int r, g, b; //Initialization Y = src; V = Y + width * height; U = Y + width * height + width * height / 4; pty1 = Y; pty2 = pty1 + width; RGB1 = dst; RGB2 = RGB1 + 3 * width; for (j = 0; j < height; j += 2) { //printf ("process line %d\n",j); for (i = 0; i < width; i += 2) { if (flipUV) { u = (*V++) - 128; v = (*U++) - 128; } else { v = (*V++) - 128; u = (*U++) - 128; } switch (ColSpace) { // M$ color space case 0: { v1 = ((v << 10) + (v << 9) + (v << 6) + (v << 5)) >> 10; // 1.593 u1 = ((u << 8) + (u << 7) + (u << 4)) >> 10; // 0.390 v2 = ((v << 9) + (v << 4)) >> 10; // 0.515 u2 = ((u << 11) + (u << 4)) >> 10; // 2.015 } break; // PAL specific case 1: { v1 = ((v << 10) + (v << 7) + (v << 4)) >> 10; // 1.1406 u1 = ((u << 8) + (u << 7) + (u << 4) + (u << 3)) >> 10; // 0.3984 v2 = ((v << 9) + (v << 6) + (v << 4) + (v << 1)) >> 10; // 0.5800 u2 = ((u << 11) + (u << 5)) >> 10; // 2.0312 } break; // V4l2 case 2: { v1 = ((v << 10) + (v << 8) + (v << 7) + (v << 5)) >> 10; // 1.406 u1 = ((u << 8) + (u << 6) + (u << 5)) >> 10; // 0.343 v2 = ((v << 9) + (v << 7) + (v << 6) + (v << 5)) >> 10; // 0.718 u2 = ((u << 10) + (u << 9) + (u << 8) + (u << 4) + (u << 3)) >> 10; // 1.773 } break; case 3: { v1 = u1 = v2 = u2 = 0; } break; default: break; } //up-left y1 = (*pty1++); if (y1 > 0) { r = y1 + (v1); g = y1 - (u1) - (v2); b = y1 + (u2); r = CLIP (r); g = CLIP (g); b = CLIP (b); } else { r = g = b = 0; } *RGB1++ = r; *RGB1++ = g; *RGB1++ = b; //down-left y2 = (*pty2++); if (y2 > 0) { r = y2 + (v1); g = y2 - (u1) - (v2); b = y2 + (u2); r = CLIP (r); g = CLIP (g); b = CLIP (b); } else { r = b = g = 0; } *RGB2++ = r; *RGB2++ = g; *RGB2++ = b; //up-right y1 = (*pty1++); if (y1 > 0) { r = y1 + (v1); g = y1 - (u1) - (v2); b = y1 + (u2); r = CLIP (r); g = CLIP (g); b = CLIP (b); } else { r = g = b = 0; } *RGB1++ = r; *RGB1++ = g; *RGB1++ = b; //down-right y2 = (*pty2++); if (y2 > 0) { r = y2 + (v1); g = y2 - (u1) - (v2); b = y2 + (u2); r = CLIP (r); g = CLIP (g); b = CLIP (b); } else { r = b = g = 0; } *RGB2++ = r; *RGB2++ = g; *RGB2++ = b; } RGB1 += 3 * width; RGB2 += 3 * width; pty1 += width; pty2 += width; }//printf ("done YUV420 -> RGB \n");}int get_jpegsize (unsigned char *buf, int insize){ int i; for ( i= 1024 ; i< insize; i++) { if ((buf[i] == 0xFF) && (buf[i+1] == 0xD9)) return i+10; } return -1;}/****************************************************************************//* * linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder. * * (w) August 2001 by Michael Schroeder, <mls@suse.de> * */ /* february 2005 by Michel Xhaard, <mxhaard at magic dot fr > change only produce RGB24 output flip R and B component Realloc output buffer if width and height change rewrite error check in jpeg_decode update include for userspace use decode 221111 jpeg411 and 211111 jpeg422 stream *//****************************************************************************/#define ISHIFT 11#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))#define IMULT(a, b) (((a) * (b)) >> ISHIFT)#define ITOINT(a) ((a) >> ISHIFT)#ifndef __P# define __P(x) x#endif/* special markers */#define M_BADHUFF -1#define M_EOF 0x80struct jpeg_decdata { int dcts[6 * 64 + 16]; int out[64 * 6]; int dquant[3][64];};struct in { unsigned char *p; unsigned int bits; int left; int marker; int (*func) __P((void *)); void *data;};/*********************************/struct dec_hufftbl;struct enc_hufftbl;union hufftblp { struct dec_hufftbl *dhuff; struct enc_hufftbl *ehuff;};struct scan { int dc; /* old dc value */ union hufftblp hudc; union hufftblp huac; int next; /* when to switch to next scan */ int cid; /* component id */ int hv; /* horiz/vert, copied from comp */ int tq; /* quant tbl, copied from comp */};/*********************************/#define DECBITS 10 /* seems to be the optimum */struct dec_hufftbl { int maxcode[17]; int valptr[16]; unsigned char vals[256]; unsigned int llvals[1 << DECBITS];};static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));static int dec_readmarker __P((struct in *));static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));static void setinput __P((struct in *, unsigned char *));/*********************************/#undef PREC#define PREC intstatic void idctqtab __P((unsigned char *, PREC *));static void idct __P((int *, int *, PREC *, PREC, int));static void scaleidctqtab __P((PREC *, PREC));/*********************************/static void initcol __P((PREC[][64]));static void col221111 __P((int *, unsigned char *, int));/*********************************/#define M_SOI 0xd8#define M_APP0 0xe0#define M_DQT 0xdb#define M_SOF0 0xc0#define M_DHT 0xc4#define M_DRI 0xdd#define M_SOS 0xda#define M_RST0 0xd0#define M_EOI 0xd9#define M_COM 0xfestatic unsigned char *datap;static int getbyte(void){ return *datap++;}static int getword(void){ int c1, c2; c1 = *datap++; c2 = *datap++; return c1 << 8 | c2;}struct comp { int cid; int hv; int tq;};#define MAXCOMP 4struct jpginfo { int nc; /* number of components */ int ns; /* number of scans */ int dri; /* restart interval */ int nm; /* mcus til next marker */ int rm; /* next restart marker */};static struct jpginfo info;static struct comp comps[MAXCOMP];static struct scan dscans[MAXCOMP];static unsigned char quant[4][64];static struct dec_hufftbl dhuff[4];#define dec_huffdc (dhuff + 0)#define dec_huffac (dhuff + 2)static struct in in;static int readtables(int till){ int m, l, i, j, lq, pq, tq; int tc, th, tt; for (;;) { if (getbyte() != 0xff) return -1; if ((m = getbyte()) == till) break; switch (m) { case 0xc2: return 0; case M_DQT: lq = getword(); while (lq > 2) { pq = getbyte(); tq = pq & 15; if (tq > 3) return -1; pq >>= 4; if (pq != 0) return -1; for (i = 0; i < 64; i++) quant[tq][i] = getbyte(); lq -= 64 + 1; } break; case M_DHT: l = getword(); while (l > 2) { int hufflen[16], k; unsigned char huffvals[256]; tc = getbyte(); th = tc & 15; tc >>= 4; tt = tc * 2 + th; if (tc > 1 || th > 1) return -1; for (i = 0; i < 16; i++) hufflen[i] = getbyte(); l -= 1 + 16; k = 0; for (i = 0; i < 16; i++) { for (j = 0; j < hufflen[i]; j++) huffvals[k++] = getbyte(); l -= hufflen[i]; } dec_makehuff(dhuff + tt, hufflen, huffvals); } break; case M_DRI: l = getword(); info.dri = getword(); break; default: l = getword(); while (l-- > 2) getbyte(); break; } } return 0;}static void dec_initscans(void){ int i; info.nm = info.dri + 1; info.rm = M_RST0; for (i = 0; i < info.ns; i++) dscans[i].dc = 0;}static int dec_checkmarker(void){ int i; if (dec_readmarker(&in) != info.rm) return -1; info.nm = info.dri; info.rm = (info.rm + 1) & ~0x08; for (i = 0; i < info.ns; i++) dscans[i].dc = 0; return 0;}int jpeg_decode(unsigned char **pic, unsigned char *buf, int *width, int *height ){ struct jpeg_decdata *decdata; int i, j, m, tac, tdc; int intwidth ,intheight; int mcusx, mcusy, mx, my; int max[6]; int err = 0; int enc411 = 1; decdata = (struct jpeg_decdata*)malloc(sizeof(struct jpeg_decdata)); if (!decdata){ err= -1; goto error; } if (buf == NULL){ err = -1; goto error; } datap = buf; if (getbyte() != 0xff){ err= ERR_NO_SOI; goto error; } if (getbyte() != M_SOI){ err= ERR_NO_SOI; goto error; } if (readtables(M_SOF0)){ err= ERR_BAD_TABLES; goto error; } getword(); i = getbyte(); if (i != 8){ err = ERR_NOT_8BIT; goto error; } intheight = getword(); intwidth = getword(); //if ((intheight & 15) || (intwidth & 15)){ if ((intheight & 7) || (intwidth & 15)){ err = ERR_BAD_WIDTH_OR_HEIGHT; goto error; } info.nc = getbyte(); if (info.nc > MAXCOMP){ err = ERR_TOO_MANY_COMPPS; goto error; } for (i = 0; i < info.nc; i++) { int h, v; comps[i].cid = getbyte(); comps[i].hv = getbyte(); v = comps[i].hv & 15; h = comps[i].hv >> 4; comps[i].tq = getbyte(); if (h > 3 || v > 3){ err = ERR_ILLEGAL_HV; goto error; } if (comps[i].tq > 3){ err = ERR_QUANT_TABLE_SELECTOR; goto error; } } if (readtables(M_SOS)){ err = ERR_BAD_TABLES; goto error; } getword(); info.ns = getbyte(); if (info.ns != 3){ err = ERR_NOT_YCBCR_221111; goto error; } for (i = 0; i < 3; i++) { dscans[i].cid = getbyte(); tdc = getbyte(); tac = tdc & 15; tdc >>= 4; if (tdc > 1 || tac > 1){ err = ERR_QUANT_TABLE_SELECTOR; goto error; } for (j = 0; j < info.nc; j++) if (comps[j].cid == dscans[i].cid) break; if (j == info.nc){ err= ERR_UNKNOWN_CID_IN_SCAN; goto error; } dscans[i].hv = comps[j].hv; dscans[i].tq = comps[j].tq; dscans[i].hudc.dhuff = dec_huffdc + tdc; dscans[i].huac.dhuff = dec_huffac + tac; } i = getbyte(); j = getbyte(); m = getbyte(); if (i != 0 || j != 63 || m != 0){ err = ERR_NOT_SEQUENTIAL_DCT; goto error; } if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3){ err = ERR_NOT_YCBCR_221111; goto error; } if (dscans[1].hv != 0x11 || dscans[2].hv != 0x11){ err = ERR_NOT_YCBCR_221111; goto error; } /* if internal width and external are not the same or heigth too and pic not allocated realloc the good size and mark the change need 1 macroblock line more ?? */ if (intwidth != *width || intheight != *height || *pic == NULL){ *width = intwidth;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -