├── Makefile ├── Makefile.build ├── README.md ├── UVC ├── Makefile └── myuvc.c ├── convert ├── Makefile ├── color.c ├── color.h ├── convert_manager.c ├── jdatasrc-tj.c ├── jerror.h ├── jinclude.h ├── jpeglib.h ├── mjpeg2rgb.c ├── rgb2rgb.c └── yuv2rgb.c ├── display ├── Makefile ├── disp_manager.c └── fb.c ├── include ├── config.h ├── convert_manager.h ├── disp_manager.h ├── pic_operation.h ├── picfmt_manager.h ├── render.h └── video_manager.h ├── main.c ├── myuvc.c ├── netprint_client.c ├── qt_source ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── res.qrc ├── ui_mainwindow.h ├── videoCapture.pro └── videoCapture.pro.user ├── render ├── Makefile └── operation │ ├── Makefile │ ├── merge.c │ └── zoom.c ├── video ├── Makefile ├── uvc.c ├── v4l2.c └── video_manager.c └── 演示 ├── QT6摄像头界面 ├── QT6界面演示.mp4 ├── 演示1.jpg └── 演示2.jpg └── USB摄像头驱动展示 ├── 图片展示1.jpg ├── 图片展示2.jpg └── 监控实景展示.mp4 /Makefile: -------------------------------------------------------------------------------- 1 | 2 | CROSS_COMPILE = arm-linux- 3 | AS = $(CROSS_COMPILE)as 4 | LD = $(CROSS_COMPILE)ld 5 | CC = $(CROSS_COMPILE)gcc 6 | CPP = $(CC) -E 7 | AR = $(CROSS_COMPILE)ar 8 | NM = $(CROSS_COMPILE)nm 9 | 10 | STRIP = $(CROSS_COMPILE)strip 11 | OBJCOPY = $(CROSS_COMPILE)objcopy 12 | OBJDUMP = $(CROSS_COMPILE)objdump 13 | 14 | export AS LD CC CPP AR NM 15 | export STRIP OBJCOPY OBJDUMP 16 | 17 | CFLAGS := -Wall -Werror -O2 -g 18 | CFLAGS += -I $(shell pwd)/include 19 | 20 | LDFLAGS := -lm -ljpeg 21 | 22 | export CFLAGS LDFLAGS 23 | 24 | TOPDIR := $(shell pwd) 25 | export TOPDIR 26 | 27 | TARGET := video2lcd 28 | 29 | 30 | obj-y += main.o 31 | obj-y += convert/ 32 | obj-y += display/ 33 | obj-y += render/ 34 | obj-y += video/ 35 | 36 | all : 37 | make -C ./ -f $(TOPDIR)/Makefile.build 38 | $(CC) $(LDFLAGS) -o $(TARGET) built-in.o 39 | 40 | 41 | clean: 42 | rm -f $(shell find -name "*.o") 43 | rm -f $(TARGET) 44 | 45 | distclean: 46 | rm -f $(shell find -name "*.o") 47 | rm -f $(shell find -name "*.d") 48 | rm -f $(TARGET) 49 | -------------------------------------------------------------------------------- /Makefile.build: -------------------------------------------------------------------------------- 1 | PHONY := __build 2 | __build: 3 | 4 | 5 | obj-y := 6 | subdir-y := 7 | 8 | include Makefile 9 | 10 | # obj-y := a.o b.o c/ d/ 11 | # $(filter %/, $(obj-y)) : c/ d/ 12 | # __subdir-y : c d 13 | # subdir-y : c d 14 | __subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) 15 | subdir-y += $(__subdir-y) 16 | 17 | # c/built-in.o d/built-in.o 18 | subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o) 19 | 20 | # a.o b.o 21 | cur_objs := $(filter-out %/, $(obj-y)) 22 | dep_files := $(foreach f,$(cur_objs),.$(f).d) 23 | dep_files := $(wildcard $(dep_files)) 24 | 25 | ifneq ($(dep_files),) 26 | include $(dep_files) 27 | endif 28 | 29 | 30 | PHONY += $(subdir-y) 31 | 32 | 33 | __build : $(subdir-y) built-in.o 34 | 35 | $(subdir-y): 36 | make -C $@ -f $(TOPDIR)/Makefile.build 37 | 38 | built-in.o : $(cur_objs) $(subdir_objs) 39 | $(LD) -r -o $@ $^ 40 | 41 | dep_file = .$@.d 42 | 43 | %.o : %.c 44 | $(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $< 45 | 46 | .PHONY : $(PHONY) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VideoSurveillance 2 | 使用IMX6ULL ,基于 linux 4.9.88 版本内核编写的USB摄像头驱动应用程序。 3 | 4 | QT6:将usb摄像头连接至IMX后,通过QT6 的 Multimedia 和 Multimedia Widget 模块检测开发板的摄像头设备,实现视频监控,录像以及拍照功能。 5 | 6 | -------------------------------------------------------------------------------- /UVC/Makefile: -------------------------------------------------------------------------------- 1 | KERN_DIR = /usr/src/linux-headers-2.6.31-14-generic 2 | 3 | all: 4 | make -C $(KERN_DIR) M=`pwd` modules 5 | 6 | clean: 7 | make -C $(KERN_DIR) M=`pwd` modules clean 8 | rm -rf modules.order 9 | 10 | obj-m += myuvc.o 11 | -------------------------------------------------------------------------------- /UVC/myuvc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/UVC/myuvc.c -------------------------------------------------------------------------------- /convert/Makefile: -------------------------------------------------------------------------------- 1 | obj-y += convert_manager.o 2 | obj-y += yuv2rgb.o 3 | obj-y += color.o 4 | obj-y += mjpeg2rgb.o 5 | obj-y += jdatasrc-tj.o 6 | obj-y += rgb2rgb.o 7 | -------------------------------------------------------------------------------- /convert/color.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | # GspcaGui: Gspca/Spca5xx Grabber # 3 | # Copyright (C) 2004 2005 2006 Michel Xhaard # 4 | # # 5 | # This program is free software; you can redistribute it and/or modify # 6 | # it under the terms of the GNU General Public License as published by # 7 | # the Free Software Foundation; either version 2 of the License, or # 8 | # (at your option) any later version. # 9 | # # 10 | # This program is distributed in the hope that it will be useful, # 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 13 | # GNU General Public License for more details. # 14 | # # 15 | # You should have received a copy of the GNU General Public License # 16 | # along with this program; if not, write to the Free Software # 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # 18 | # # 19 | ****************************************************************************/ 20 | #include 21 | #include 22 | #include 23 | #include "color.h" 24 | 25 | static int *LutYr = NULL; 26 | static int *LutYg = NULL;; 27 | static int *LutYb = NULL;; 28 | static int *LutVr = NULL;; 29 | static int *LutVrY = NULL;; 30 | static int *LutUb = NULL;; 31 | static int *LutUbY = NULL;; 32 | static int *LutRv = NULL; 33 | static int *LutGu = NULL; 34 | static int *LutGv = NULL; 35 | static int *LutBu = NULL; 36 | 37 | #if 0 38 | #define RGB24_TO_Y(r,g,b) LutYr[(r)] + LutYg[(g)] + LutYb[(b)] 39 | #define YR_TO_V(r,y) LutVr[(r)] + LutVrY[(y)] 40 | #define YB_TO_U(b,y) LutUb[(b)] + LutUbY[(y)] 41 | 42 | #define R_FROMYV(y,v) CLIP((y) + LutRv[(v)]) 43 | #define G_FROMYUV(y,u,v) CLIP((y) + LutGu[(u)] + LutGv[(v)]) 44 | #define B_FROMYU(y,u) CLIP((y) + LutBu[(u)]) 45 | #endif 46 | 47 | unsigned char 48 | RGB24_TO_Y(unsigned char r, unsigned char g, unsigned char b) 49 | { 50 | return (LutYr[(r)] + LutYg[(g)] + LutYb[(b)]); 51 | } 52 | unsigned char 53 | YR_TO_V(unsigned char r, unsigned char y) 54 | { 55 | return (LutVr[(r)] + LutVrY[(y)]); 56 | } 57 | unsigned char 58 | YB_TO_U(unsigned char b, unsigned char y) 59 | { 60 | return (LutUb[(b)] + LutUbY[(y)]); 61 | } 62 | unsigned char 63 | R_FROMYV(unsigned char y, unsigned char v) 64 | { 65 | return CLIP((y) + LutRv[(v)]); 66 | } 67 | unsigned char 68 | G_FROMYUV(unsigned char y, unsigned char u, unsigned char v) 69 | { 70 | return CLIP((y) + LutGu[(u)] + LutGv[(v)]); 71 | } 72 | unsigned char 73 | B_FROMYU(unsigned char y, unsigned char u) 74 | { 75 | return CLIP((y) + LutBu[(u)]); 76 | } 77 | 78 | void initLut(void) 79 | { 80 | int i; 81 | #define Rcoef 299 82 | #define Gcoef 587 83 | #define Bcoef 114 84 | #define Vrcoef 711 //656 //877 85 | #define Ubcoef 560 //500 //493 564 86 | 87 | #define CoefRv 1402 88 | #define CoefGu 714 // 344 89 | #define CoefGv 344 // 714 90 | #define CoefBu 1772 91 | 92 | LutYr = malloc(256*sizeof(int)); 93 | LutYg = malloc(256*sizeof(int)); 94 | LutYb = malloc(256*sizeof(int)); 95 | LutVr = malloc(256*sizeof(int)); 96 | LutVrY = malloc(256*sizeof(int)); 97 | LutUb = malloc(256*sizeof(int)); 98 | LutUbY = malloc(256*sizeof(int)); 99 | 100 | LutRv = malloc(256*sizeof(int)); 101 | LutGu = malloc(256*sizeof(int)); 102 | LutGv = malloc(256*sizeof(int)); 103 | LutBu = malloc(256*sizeof(int)); 104 | for (i= 0;i < 256;i++){ 105 | LutYr[i] = i*Rcoef/1000 ; 106 | LutYg[i] = i*Gcoef/1000 ; 107 | LutYb[i] = i*Bcoef/1000 ; 108 | LutVr[i] = i*Vrcoef/1000; 109 | LutUb[i] = i*Ubcoef/1000; 110 | LutVrY[i] = 128 -(i*Vrcoef/1000); 111 | LutUbY[i] = 128 -(i*Ubcoef/1000); 112 | LutRv[i] = (i-128)*CoefRv/1000; 113 | LutBu[i] = (i-128)*CoefBu/1000; 114 | LutGu[i] = (128-i)*CoefGu/1000; 115 | LutGv[i] = (128-i)*CoefGv/1000; 116 | } 117 | } 118 | 119 | 120 | void freeLut(void){ 121 | free(LutYr); 122 | free(LutYg); 123 | free(LutYb); 124 | free(LutVr); 125 | free(LutVrY); 126 | free(LutUb); 127 | free(LutUbY); 128 | 129 | free(LutRv); 130 | free(LutGu); 131 | free(LutGv); 132 | free(LutBu); 133 | } 134 | 135 | -------------------------------------------------------------------------------- /convert/color.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | # GspcaGui: Gspca/Spca5xx Grabber # 3 | # Copyright (C) 2004 2005 2006 Michel Xhaard # 4 | # # 5 | # This program is free software; you can redistribute it and/or modify # 6 | # it under the terms of the GNU General Public License as published by # 7 | # the Free Software Foundation; either version 2 of the License, or # 8 | # (at your option) any later version. # 9 | # # 10 | # This program is distributed in the hope that it will be useful, # 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 13 | # GNU General Public License for more details. # 14 | # # 15 | # You should have received a copy of the GNU General Public License # 16 | # along with this program; if not, write to the Free Software # 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # 18 | # # 19 | ****************************************************************************/ 20 | typedef struct Myrgb16 { 21 | unsigned short blue:5; 22 | unsigned short green:6; 23 | unsigned short red:5; 24 | } Myrgb16; 25 | typedef struct Myrgb24 { 26 | unsigned char blue; 27 | unsigned char green; 28 | unsigned char red; 29 | } Myrgb24; 30 | typedef struct Myrgb32 { 31 | unsigned char blue; 32 | unsigned char green; 33 | unsigned char red; 34 | unsigned char alpha; 35 | } Myrgb32; 36 | 37 | typedef struct MyYUV422 { 38 | unsigned char y0; 39 | unsigned char u; 40 | unsigned char y1; 41 | unsigned char v; 42 | } MyYUV422; 43 | 44 | typedef struct MyYUV444 { 45 | unsigned char y; 46 | unsigned char u; 47 | unsigned char v; 48 | } MyYUV444; 49 | 50 | #define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color))) 51 | 52 | unsigned char 53 | RGB24_TO_Y(unsigned char r, unsigned char g, unsigned char b); 54 | 55 | unsigned char 56 | YR_TO_V(unsigned char r, unsigned char y); 57 | 58 | unsigned char 59 | YB_TO_U(unsigned char b, unsigned char y); 60 | 61 | unsigned char 62 | R_FROMYV(unsigned char y, unsigned char v); 63 | 64 | unsigned char 65 | G_FROMYUV(unsigned char y, unsigned char u, unsigned char v); 66 | 67 | unsigned char 68 | B_FROMYU(unsigned char y, unsigned char u); 69 | 70 | #define YfromRGB(r,g,b) CLIP((77*(r)+150*(g)+29*(b))>>8) 71 | #define UfromRGB(r,g,b) CLIP(((128*(b)-85*(g)-43*(r))>>8 )+128) 72 | #define VfromRGB(r,g,b) CLIP(((128*(r)-107*(g)-21*(b))>>8) +128) 73 | 74 | #define PACKRGB16(r,g,b) (__u16) ((((b) & 0xF8) << 8 ) | (((g) & 0xFC) << 3 ) | (((r) & 0xF8) >> 3 )) 75 | #define UNPACK16(pixel,r,g,b) r=((pixel)&0xf800) >> 8; g=((pixel)&0x07e0) >> 3; b=(((pixel)&0x001f) << 3) 76 | 77 | void initLut(void); 78 | void freeLut(void); 79 | -------------------------------------------------------------------------------- /convert/convert_manager.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | static PT_VideoConvert g_ptVideoConvertHead = NULL; 7 | 8 | /*注册视频转换结构体*/ 9 | /*将 ptVideoConvert 插到ptTmp 尾端*/ 10 | int RegisterVideoConvert(PT_VideoConvert ptVideoConvert) 11 | { 12 | PT_VideoConvert ptTmp; 13 | 14 | if (!g_ptVideoConvertHead) 15 | { 16 | g_ptVideoConvertHead = ptVideoConvert; 17 | ptVideoConvert->ptNext = NULL; 18 | } 19 | else 20 | { 21 | ptTmp = g_ptVideoConvertHead; 22 | while (ptTmp->ptNext) 23 | { 24 | ptTmp = ptTmp->ptNext; 25 | } 26 | ptTmp->ptNext = ptVideoConvert; 27 | ptVideoConvert->ptNext = NULL; 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | 34 | /* */ 35 | void ShowVideoConvert(void) 36 | { 37 | int i = 0; 38 | PT_VideoConvert ptTmp = g_ptVideoConvertHead; 39 | 40 | while (ptTmp) 41 | { 42 | printf("%02d %s\n", i++, ptTmp->name); 43 | ptTmp = ptTmp->ptNext; 44 | } 45 | } 46 | 47 | /**/ 48 | PT_VideoConvert GetVideoConvert(char *pcName) 49 | { 50 | PT_VideoConvert ptTmp = g_ptVideoConvertHead; 51 | 52 | while (ptTmp) 53 | { 54 | if (strcmp(ptTmp->name, pcName) == 0) 55 | { 56 | return ptTmp; 57 | } 58 | ptTmp = ptTmp->ptNext; 59 | } 60 | return NULL; 61 | } 62 | 63 | PT_VideoConvert GetVideoConvertForFormats(int iPixelFormatIn, int iPixelFormatOut) 64 | { 65 | PT_VideoConvert ptTmp = g_ptVideoConvertHead; 66 | 67 | while (ptTmp) 68 | { 69 | if (ptTmp->isSupport(iPixelFormatIn, iPixelFormatOut)) 70 | { 71 | return ptTmp; 72 | } 73 | ptTmp = ptTmp->ptNext; 74 | } 75 | return NULL; 76 | } 77 | 78 | /*初始化*/ 79 | int VideoConvertInit(void) 80 | { 81 | int iError; 82 | 83 | iError = Yuv2RgbInit(); 84 | iError |= Mjpeg2RgbInit(); 85 | iError |= Rgb2RgbInit(); 86 | 87 | return iError; 88 | } 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /convert/jdatasrc-tj.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jdatasrc.c 3 | * 4 | * Copyright (C) 1994-1996, Thomas G. Lane. 5 | * Modified 2009-2010 by Guido Vollbeding. 6 | * This file is part of the Independent JPEG Group's software. 7 | * For conditions of distribution and use, see the accompanying README file. 8 | * 9 | * This file contains decompression data source routines for the case of 10 | * reading JPEG data from memory or from a file (or any stdio stream). 11 | * While these routines are sufficient for most applications, 12 | * some will want to use a different source manager. 13 | * IMPORTANT: we assume that fread() will correctly transcribe an array of 14 | * JOCTETs from 8-bit-wide elements on external storage. If char is wider 15 | * than 8 bits on your machine, you may need to do some tweaking. 16 | */ 17 | 18 | /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 19 | #include "jinclude.h" 20 | #include "jpeglib.h" 21 | #include "jerror.h" 22 | 23 | 24 | /* 25 | * Initialize source --- called by jpeg_read_header 26 | * before any data is actually read. 27 | */ 28 | 29 | METHODDEF(void) 30 | init_mem_source (j_decompress_ptr cinfo) 31 | { 32 | /* no work necessary here */ 33 | } 34 | 35 | 36 | /* 37 | * Fill the input buffer --- called whenever buffer is emptied. 38 | * 39 | * In typical applications, this should read fresh data into the buffer 40 | * (ignoring the current state of next_input_byte & bytes_in_buffer), 41 | * reset the pointer & count to the start of the buffer, and return TRUE 42 | * indicating that the buffer has been reloaded. It is not necessary to 43 | * fill the buffer entirely, only to obtain at least one more byte. 44 | * 45 | * There is no such thing as an EOF return. If the end of the file has been 46 | * reached, the routine has a choice of ERREXIT() or inserting fake data into 47 | * the buffer. In most cases, generating a warning message and inserting a 48 | * fake EOI marker is the best course of action --- this will allow the 49 | * decompressor to output however much of the image is there. However, 50 | * the resulting error message is misleading if the real problem is an empty 51 | * input file, so we handle that case specially. 52 | * 53 | * In applications that need to be able to suspend compression due to input 54 | * not being available yet, a FALSE return indicates that no more data can be 55 | * obtained right now, but more may be forthcoming later. In this situation, 56 | * the decompressor will return to its caller (with an indication of the 57 | * number of scanlines it has read, if any). The application should resume 58 | * decompression after it has loaded more data into the input buffer. Note 59 | * that there are substantial restrictions on the use of suspension --- see 60 | * the documentation. 61 | * 62 | * When suspending, the decompressor will back up to a convenient restart point 63 | * (typically the start of the current MCU). next_input_byte & bytes_in_buffer 64 | * indicate where the restart point will be if the current call returns FALSE. 65 | * Data beyond this point must be rescanned after resumption, so move it to 66 | * the front of the buffer rather than discarding it. 67 | */ 68 | 69 | METHODDEF(boolean) 70 | fill_mem_input_buffer (j_decompress_ptr cinfo) 71 | { 72 | static JOCTET mybuffer[4]; 73 | 74 | /* The whole JPEG data is expected to reside in the supplied memory 75 | * buffer, so any request for more data beyond the given buffer size 76 | * is treated as an error. 77 | */ 78 | WARNMS(cinfo, JWRN_JPEG_EOF); 79 | /* Insert a fake EOI marker */ 80 | mybuffer[0] = (JOCTET) 0xFF; 81 | mybuffer[1] = (JOCTET) JPEG_EOI; 82 | 83 | cinfo->src->next_input_byte = mybuffer; 84 | cinfo->src->bytes_in_buffer = 2; 85 | 86 | return TRUE; 87 | } 88 | 89 | 90 | /* 91 | * Skip data --- used to skip over a potentially large amount of 92 | * uninteresting data (such as an APPn marker). 93 | * 94 | * Writers of suspendable-input applications must note that skip_input_data 95 | * is not granted the right to give a suspension return. If the skip extends 96 | * beyond the data currently in the buffer, the buffer can be marked empty so 97 | * that the next read will cause a fill_input_buffer call that can suspend. 98 | * Arranging for additional bytes to be discarded before reloading the input 99 | * buffer is the application writer's problem. 100 | */ 101 | 102 | METHODDEF(void) 103 | skip_input_data (j_decompress_ptr cinfo, long num_bytes) 104 | { 105 | struct jpeg_source_mgr * src = cinfo->src; 106 | 107 | /* Just a dumb implementation for now. Could use fseek() except 108 | * it doesn't work on pipes. Not clear that being smart is worth 109 | * any trouble anyway --- large skips are infrequent. 110 | */ 111 | if (num_bytes > 0) { 112 | while (num_bytes > (long) src->bytes_in_buffer) { 113 | num_bytes -= (long) src->bytes_in_buffer; 114 | (void) (*src->fill_input_buffer) (cinfo); 115 | /* note we assume that fill_input_buffer will never return FALSE, 116 | * so suspension need not be handled. 117 | */ 118 | } 119 | src->next_input_byte += (size_t) num_bytes; 120 | src->bytes_in_buffer -= (size_t) num_bytes; 121 | } 122 | } 123 | 124 | 125 | /* 126 | * An additional method that can be provided by data source modules is the 127 | * resync_to_restart method for error recovery in the presence of RST markers. 128 | * For the moment, this source module just uses the default resync method 129 | * provided by the JPEG library. That method assumes that no backtracking 130 | * is possible. 131 | */ 132 | 133 | 134 | /* 135 | * Terminate source --- called by jpeg_finish_decompress 136 | * after all data has been read. Often a no-op. 137 | * 138 | * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 139 | * application must deal with any cleanup that should happen even 140 | * for error exit. 141 | */ 142 | 143 | METHODDEF(void) 144 | term_source (j_decompress_ptr cinfo) 145 | { 146 | /* no work necessary here */ 147 | } 148 | 149 | 150 | /* 151 | * Prepare for input from a supplied memory buffer. 152 | * The buffer must contain the whole JPEG data. 153 | */ 154 | 155 | GLOBAL(void) 156 | jpeg_mem_src_tj (j_decompress_ptr cinfo, 157 | unsigned char * inbuffer, unsigned long insize) 158 | { 159 | struct jpeg_source_mgr * src; 160 | 161 | if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */ 162 | ERREXIT(cinfo, JERR_INPUT_EMPTY); 163 | 164 | /* The source object is made permanent so that a series of JPEG images 165 | * can be read from the same buffer by calling jpeg_mem_src only before 166 | * the first one. 167 | */ 168 | if (cinfo->src == NULL) { /* first time for this JPEG object? */ 169 | cinfo->src = (struct jpeg_source_mgr *) 170 | (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 171 | SIZEOF(struct jpeg_source_mgr)); 172 | } 173 | 174 | src = cinfo->src; 175 | src->init_source = init_mem_source; 176 | src->fill_input_buffer = fill_mem_input_buffer; 177 | src->skip_input_data = skip_input_data; 178 | src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ 179 | src->term_source = term_source; 180 | src->bytes_in_buffer = (size_t) insize; 181 | src->next_input_byte = (JOCTET *) inbuffer; 182 | } 183 | -------------------------------------------------------------------------------- /convert/jerror.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jerror.h 3 | * 4 | * Copyright (C) 1994-1997, Thomas G. Lane. 5 | * Modified 1997-2009 by Guido Vollbeding. 6 | * This file is part of the Independent JPEG Group's software. 7 | * For conditions of distribution and use, see the accompanying README file. 8 | * 9 | * This file defines the error and message codes for the JPEG library. 10 | * Edit this file to add new codes, or to translate the message strings to 11 | * some other language. 12 | * A set of error-reporting macros are defined too. Some applications using 13 | * the JPEG library may wish to include this file to get the error codes 14 | * and/or the macros. 15 | */ 16 | 17 | /* 18 | * To define the enum list of message codes, include this file without 19 | * defining macro JMESSAGE. To create a message string table, include it 20 | * again with a suitable JMESSAGE definition (see jerror.c for an example). 21 | */ 22 | #ifndef JMESSAGE 23 | #ifndef JERROR_H 24 | /* First time through, define the enum list */ 25 | #define JMAKE_ENUM_LIST 26 | #else 27 | /* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ 28 | #define JMESSAGE(code,string) 29 | #endif /* JERROR_H */ 30 | #endif /* JMESSAGE */ 31 | 32 | #ifdef JMAKE_ENUM_LIST 33 | 34 | typedef enum { 35 | 36 | #define JMESSAGE(code,string) code , 37 | 38 | #endif /* JMAKE_ENUM_LIST */ 39 | 40 | JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ 41 | 42 | /* For maintenance convenience, list is alphabetical by message code name */ 43 | #if JPEG_LIB_VERSION < 70 44 | JMESSAGE(JERR_ARITH_NOTIMPL, 45 | "Sorry, arithmetic coding is not implemented") 46 | #endif 47 | JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") 48 | JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") 49 | JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") 50 | JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") 51 | #if JPEG_LIB_VERSION >= 70 52 | JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") 53 | #endif 54 | JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") 55 | JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") 56 | #if JPEG_LIB_VERSION >= 70 57 | JMESSAGE(JERR_BAD_DROP_SAMPLING, 58 | "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c") 59 | #endif 60 | JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") 61 | JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") 62 | JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") 63 | JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") 64 | JMESSAGE(JERR_BAD_LIB_VERSION, 65 | "Wrong JPEG library version: library is %d, caller expects %d") 66 | JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") 67 | JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") 68 | JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") 69 | JMESSAGE(JERR_BAD_PROGRESSION, 70 | "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") 71 | JMESSAGE(JERR_BAD_PROG_SCRIPT, 72 | "Invalid progressive parameters at scan script entry %d") 73 | JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") 74 | JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") 75 | JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") 76 | JMESSAGE(JERR_BAD_STRUCT_SIZE, 77 | "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") 78 | JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") 79 | JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") 80 | JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") 81 | JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") 82 | JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") 83 | JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") 84 | JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") 85 | JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") 86 | JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") 87 | JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") 88 | JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") 89 | JMESSAGE(JERR_EMS_READ, "Read from EMS failed") 90 | JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") 91 | JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") 92 | JMESSAGE(JERR_FILE_READ, "Input file read error") 93 | JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") 94 | JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") 95 | JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") 96 | JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") 97 | JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") 98 | JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") 99 | JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") 100 | JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, 101 | "Cannot transcode due to multiple use of quantization table %d") 102 | JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") 103 | JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") 104 | JMESSAGE(JERR_NOTIMPL, "Not implemented yet") 105 | JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") 106 | #if JPEG_LIB_VERSION >= 70 107 | JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") 108 | #endif 109 | JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") 110 | JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") 111 | JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") 112 | JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") 113 | JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") 114 | JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") 115 | JMESSAGE(JERR_QUANT_COMPONENTS, 116 | "Cannot quantize more than %d color components") 117 | JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") 118 | JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") 119 | JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") 120 | JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") 121 | JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") 122 | JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") 123 | JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") 124 | JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") 125 | JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") 126 | JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") 127 | JMESSAGE(JERR_TFILE_WRITE, 128 | "Write failed on temporary file --- out of disk space?") 129 | JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") 130 | JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") 131 | JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") 132 | JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") 133 | JMESSAGE(JERR_XMS_READ, "Read from XMS failed") 134 | JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") 135 | JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) 136 | JMESSAGE(JMSG_VERSION, JVERSION) 137 | JMESSAGE(JTRC_16BIT_TABLES, 138 | "Caution: quantization tables are too coarse for baseline JPEG") 139 | JMESSAGE(JTRC_ADOBE, 140 | "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") 141 | JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") 142 | JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") 143 | JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") 144 | JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") 145 | JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") 146 | JMESSAGE(JTRC_DRI, "Define Restart Interval %u") 147 | JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") 148 | JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") 149 | JMESSAGE(JTRC_EOI, "End Of Image") 150 | JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") 151 | JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") 152 | JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, 153 | "Warning: thumbnail image size does not match data length %u") 154 | JMESSAGE(JTRC_JFIF_EXTENSION, 155 | "JFIF extension marker: type 0x%02x, length %u") 156 | JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") 157 | JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") 158 | JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") 159 | JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") 160 | JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") 161 | JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") 162 | JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") 163 | JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") 164 | JMESSAGE(JTRC_RST, "RST%d") 165 | JMESSAGE(JTRC_SMOOTH_NOTIMPL, 166 | "Smoothing not supported with nonstandard sampling ratios") 167 | JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") 168 | JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") 169 | JMESSAGE(JTRC_SOI, "Start of Image") 170 | JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") 171 | JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") 172 | JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") 173 | JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") 174 | JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") 175 | JMESSAGE(JTRC_THUMB_JPEG, 176 | "JFIF extension marker: JPEG-compressed thumbnail image, length %u") 177 | JMESSAGE(JTRC_THUMB_PALETTE, 178 | "JFIF extension marker: palette thumbnail image, length %u") 179 | JMESSAGE(JTRC_THUMB_RGB, 180 | "JFIF extension marker: RGB thumbnail image, length %u") 181 | JMESSAGE(JTRC_UNKNOWN_IDS, 182 | "Unrecognized component IDs %d %d %d, assuming YCbCr") 183 | JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") 184 | JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") 185 | JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") 186 | #if JPEG_LIB_VERSION >= 70 187 | JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") 188 | #endif 189 | JMESSAGE(JWRN_BOGUS_PROGRESSION, 190 | "Inconsistent progression sequence for component %d coefficient %d") 191 | JMESSAGE(JWRN_EXTRANEOUS_DATA, 192 | "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") 193 | JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") 194 | JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") 195 | JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") 196 | JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") 197 | JMESSAGE(JWRN_MUST_RESYNC, 198 | "Corrupt JPEG data: found marker 0x%02x instead of RST%d") 199 | JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") 200 | JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") 201 | #if JPEG_LIB_VERSION < 70 202 | JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") 203 | #if defined(C_ARITH_CODING_SUPPORTED) || defined(D_ARITH_CODING_SUPPORTED) 204 | JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") 205 | JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") 206 | #endif 207 | #endif 208 | 209 | #ifdef JMAKE_ENUM_LIST 210 | 211 | JMSG_LASTMSGCODE 212 | } J_MESSAGE_CODE; 213 | 214 | #undef JMAKE_ENUM_LIST 215 | #endif /* JMAKE_ENUM_LIST */ 216 | 217 | /* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ 218 | #undef JMESSAGE 219 | 220 | 221 | #ifndef JERROR_H 222 | #define JERROR_H 223 | 224 | /* Macros to simplify using the error and trace message stuff */ 225 | /* The first parameter is either type of cinfo pointer */ 226 | 227 | /* Fatal errors (print message and exit) */ 228 | #define ERREXIT(cinfo,code) \ 229 | ((cinfo)->err->msg_code = (code), \ 230 | (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) 231 | #define ERREXIT1(cinfo,code,p1) \ 232 | ((cinfo)->err->msg_code = (code), \ 233 | (cinfo)->err->msg_parm.i[0] = (p1), \ 234 | (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) 235 | #define ERREXIT2(cinfo,code,p1,p2) \ 236 | ((cinfo)->err->msg_code = (code), \ 237 | (cinfo)->err->msg_parm.i[0] = (p1), \ 238 | (cinfo)->err->msg_parm.i[1] = (p2), \ 239 | (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) 240 | #define ERREXIT3(cinfo,code,p1,p2,p3) \ 241 | ((cinfo)->err->msg_code = (code), \ 242 | (cinfo)->err->msg_parm.i[0] = (p1), \ 243 | (cinfo)->err->msg_parm.i[1] = (p2), \ 244 | (cinfo)->err->msg_parm.i[2] = (p3), \ 245 | (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) 246 | #define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ 247 | ((cinfo)->err->msg_code = (code), \ 248 | (cinfo)->err->msg_parm.i[0] = (p1), \ 249 | (cinfo)->err->msg_parm.i[1] = (p2), \ 250 | (cinfo)->err->msg_parm.i[2] = (p3), \ 251 | (cinfo)->err->msg_parm.i[3] = (p4), \ 252 | (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) 253 | #define ERREXITS(cinfo,code,str) \ 254 | ((cinfo)->err->msg_code = (code), \ 255 | strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ 256 | (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) 257 | 258 | #define MAKESTMT(stuff) do { stuff } while (0) 259 | 260 | /* Nonfatal errors (we can keep going, but the data is probably corrupt) */ 261 | #define WARNMS(cinfo,code) \ 262 | ((cinfo)->err->msg_code = (code), \ 263 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) 264 | #define WARNMS1(cinfo,code,p1) \ 265 | ((cinfo)->err->msg_code = (code), \ 266 | (cinfo)->err->msg_parm.i[0] = (p1), \ 267 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) 268 | #define WARNMS2(cinfo,code,p1,p2) \ 269 | ((cinfo)->err->msg_code = (code), \ 270 | (cinfo)->err->msg_parm.i[0] = (p1), \ 271 | (cinfo)->err->msg_parm.i[1] = (p2), \ 272 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) 273 | 274 | /* Informational/debugging messages */ 275 | #define TRACEMS(cinfo,lvl,code) \ 276 | ((cinfo)->err->msg_code = (code), \ 277 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) 278 | #define TRACEMS1(cinfo,lvl,code,p1) \ 279 | ((cinfo)->err->msg_code = (code), \ 280 | (cinfo)->err->msg_parm.i[0] = (p1), \ 281 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) 282 | #define TRACEMS2(cinfo,lvl,code,p1,p2) \ 283 | ((cinfo)->err->msg_code = (code), \ 284 | (cinfo)->err->msg_parm.i[0] = (p1), \ 285 | (cinfo)->err->msg_parm.i[1] = (p2), \ 286 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) 287 | #define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ 288 | MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ 289 | _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ 290 | (cinfo)->err->msg_code = (code); \ 291 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) 292 | #define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ 293 | MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ 294 | _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ 295 | (cinfo)->err->msg_code = (code); \ 296 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) 297 | #define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ 298 | MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ 299 | _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ 300 | _mp[4] = (p5); \ 301 | (cinfo)->err->msg_code = (code); \ 302 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) 303 | #define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ 304 | MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ 305 | _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ 306 | _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ 307 | (cinfo)->err->msg_code = (code); \ 308 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) 309 | #define TRACEMSS(cinfo,lvl,code,str) \ 310 | ((cinfo)->err->msg_code = (code), \ 311 | strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ 312 | (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) 313 | 314 | #endif /* JERROR_H */ 315 | -------------------------------------------------------------------------------- /convert/jinclude.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jinclude.h 3 | * 4 | * Copyright (C) 1991-1994, Thomas G. Lane. 5 | * This file is part of the Independent JPEG Group's software. 6 | * For conditions of distribution and use, see the accompanying README file. 7 | * 8 | * This file exists to provide a single place to fix any problems with 9 | * including the wrong system include files. (Common problems are taken 10 | * care of by the standard jconfig symbols, but on really weird systems 11 | * you may have to edit this file.) 12 | * 13 | * NOTE: this file is NOT intended to be included by applications using the 14 | * JPEG library. Most applications need only include jpeglib.h. 15 | */ 16 | 17 | 18 | /* Include auto-config file to find out which system include files we need. */ 19 | 20 | #include "jconfig.h" /* auto configuration options */ 21 | #define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ 22 | 23 | /* 24 | * We need the NULL macro and size_t typedef. 25 | * On an ANSI-conforming system it is sufficient to include . 26 | * Otherwise, we get them from or ; we may have to 27 | * pull in as well. 28 | * Note that the core JPEG library does not require ; 29 | * only the default error handler and data source/destination modules do. 30 | * But we must pull it in because of the references to FILE in jpeglib.h. 31 | * You can remove those references if you want to compile without . 32 | */ 33 | 34 | #ifdef HAVE_STDDEF_H 35 | #include 36 | #endif 37 | 38 | #ifdef HAVE_STDLIB_H 39 | #include 40 | #endif 41 | 42 | #ifdef NEED_SYS_TYPES_H 43 | #include 44 | #endif 45 | 46 | #include 47 | 48 | /* 49 | * We need memory copying and zeroing functions, plus strncpy(). 50 | * ANSI and System V implementations declare these in . 51 | * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). 52 | * Some systems may declare memset and memcpy in . 53 | * 54 | * NOTE: we assume the size parameters to these functions are of type size_t. 55 | * Change the casts in these macros if not! 56 | */ 57 | 58 | #ifdef NEED_BSD_STRINGS 59 | 60 | #include 61 | #define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) 62 | #define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) 63 | 64 | #else /* not BSD, assume ANSI/SysV string lib */ 65 | 66 | #include 67 | #define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) 68 | #define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) 69 | 70 | #endif 71 | 72 | /* 73 | * In ANSI C, and indeed any rational implementation, size_t is also the 74 | * type returned by sizeof(). However, it seems there are some irrational 75 | * implementations out there, in which sizeof() returns an int even though 76 | * size_t is defined as long or unsigned long. To ensure consistent results 77 | * we always use this SIZEOF() macro in place of using sizeof() directly. 78 | */ 79 | 80 | #define SIZEOF(object) ((size_t) sizeof(object)) 81 | 82 | /* 83 | * The modules that use fread() and fwrite() always invoke them through 84 | * these macros. On some systems you may need to twiddle the argument casts. 85 | * CAUTION: argument order is different from underlying functions! 86 | */ 87 | 88 | #define JFREAD(file,buf,sizeofbuf) \ 89 | ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) 90 | #define JFWRITE(file,buf,sizeofbuf) \ 91 | ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) 92 | -------------------------------------------------------------------------------- /convert/jpeglib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jpeglib.h 3 | * 4 | * Copyright (C) 1991-1998, Thomas G. Lane. 5 | * Modified 2002-2009 by Guido Vollbeding. 6 | * Copyright (C) 2009-2011, D. R. Commander. 7 | * This file is part of the Independent JPEG Group's software. 8 | * For conditions of distribution and use, see the accompanying README file. 9 | * 10 | * This file defines the application interface for the JPEG library. 11 | * Most applications using the library need only include this file, 12 | * and perhaps jerror.h if they want to know the exact error codes. 13 | */ 14 | 15 | #ifndef JPEGLIB_H 16 | #define JPEGLIB_H 17 | 18 | /* 19 | * First we include the configuration files that record how this 20 | * installation of the JPEG library is set up. jconfig.h can be 21 | * generated automatically for many systems. jmorecfg.h contains 22 | * manual configuration options that most people need not worry about. 23 | */ 24 | 25 | #ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ 26 | #include "jconfig.h" /* widely used configuration options */ 27 | #endif 28 | #include "jmorecfg.h" /* seldom changed options */ 29 | 30 | 31 | #ifdef __cplusplus 32 | #ifndef DONT_USE_EXTERN_C 33 | extern "C" { 34 | #endif 35 | #endif 36 | 37 | 38 | /* Various constants determining the sizes of things. 39 | * All of these are specified by the JPEG standard, so don't change them 40 | * if you want to be compatible. 41 | */ 42 | 43 | #define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ 44 | #define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ 45 | #define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ 46 | #define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ 47 | #define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ 48 | #define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ 49 | #define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ 50 | /* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; 51 | * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. 52 | * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU 53 | * to handle it. We even let you do this from the jconfig.h file. However, 54 | * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe 55 | * sometimes emits noncompliant files doesn't mean you should too. 56 | */ 57 | #define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ 58 | #ifndef D_MAX_BLOCKS_IN_MCU 59 | #define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ 60 | #endif 61 | 62 | 63 | /* Data structures for images (arrays of samples and of DCT coefficients). 64 | * On 80x86 machines, the image arrays are too big for near pointers, 65 | * but the pointer arrays can fit in near memory. 66 | */ 67 | 68 | typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ 69 | typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ 70 | typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ 71 | 72 | typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ 73 | typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ 74 | typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ 75 | typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ 76 | 77 | typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ 78 | 79 | 80 | /* Types for JPEG compression parameters and working tables. */ 81 | 82 | 83 | /* DCT coefficient quantization tables. */ 84 | 85 | typedef struct { 86 | /* This array gives the coefficient quantizers in natural array order 87 | * (not the zigzag order in which they are stored in a JPEG DQT marker). 88 | * CAUTION: IJG versions prior to v6a kept this array in zigzag order. 89 | */ 90 | UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ 91 | /* This field is used only during compression. It's initialized FALSE when 92 | * the table is created, and set TRUE when it's been output to the file. 93 | * You could suppress output of a table by setting this to TRUE. 94 | * (See jpeg_suppress_tables for an example.) 95 | */ 96 | boolean sent_table; /* TRUE when table has been output */ 97 | } JQUANT_TBL; 98 | 99 | 100 | /* Huffman coding tables. */ 101 | 102 | typedef struct { 103 | /* These two fields directly represent the contents of a JPEG DHT marker */ 104 | UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ 105 | /* length k bits; bits[0] is unused */ 106 | UINT8 huffval[256]; /* The symbols, in order of incr code length */ 107 | /* This field is used only during compression. It's initialized FALSE when 108 | * the table is created, and set TRUE when it's been output to the file. 109 | * You could suppress output of a table by setting this to TRUE. 110 | * (See jpeg_suppress_tables for an example.) 111 | */ 112 | boolean sent_table; /* TRUE when table has been output */ 113 | } JHUFF_TBL; 114 | 115 | 116 | /* Basic info about one component (color channel). */ 117 | 118 | typedef struct { 119 | /* These values are fixed over the whole image. */ 120 | /* For compression, they must be supplied by parameter setup; */ 121 | /* for decompression, they are read from the SOF marker. */ 122 | int component_id; /* identifier for this component (0..255) */ 123 | int component_index; /* its index in SOF or cinfo->comp_info[] */ 124 | int h_samp_factor; /* horizontal sampling factor (1..4) */ 125 | int v_samp_factor; /* vertical sampling factor (1..4) */ 126 | int quant_tbl_no; /* quantization table selector (0..3) */ 127 | /* These values may vary between scans. */ 128 | /* For compression, they must be supplied by parameter setup; */ 129 | /* for decompression, they are read from the SOS marker. */ 130 | /* The decompressor output side may not use these variables. */ 131 | int dc_tbl_no; /* DC entropy table selector (0..3) */ 132 | int ac_tbl_no; /* AC entropy table selector (0..3) */ 133 | 134 | /* Remaining fields should be treated as private by applications. */ 135 | 136 | /* These values are computed during compression or decompression startup: */ 137 | /* Component's size in DCT blocks. 138 | * Any dummy blocks added to complete an MCU are not counted; therefore 139 | * these values do not depend on whether a scan is interleaved or not. 140 | */ 141 | JDIMENSION width_in_blocks; 142 | JDIMENSION height_in_blocks; 143 | /* Size of a DCT block in samples. Always DCTSIZE for compression. 144 | * For decompression this is the size of the output from one DCT block, 145 | * reflecting any scaling we choose to apply during the IDCT step. 146 | * Values of 1,2,4,8 are likely to be supported. Note that different 147 | * components may receive different IDCT scalings. 148 | */ 149 | #if JPEG_LIB_VERSION >= 70 150 | int DCT_h_scaled_size; 151 | int DCT_v_scaled_size; 152 | #else 153 | int DCT_scaled_size; 154 | #endif 155 | /* The downsampled dimensions are the component's actual, unpadded number 156 | * of samples at the main buffer (preprocessing/compression interface), thus 157 | * downsampled_width = ceil(image_width * Hi/Hmax) 158 | * and similarly for height. For decompression, IDCT scaling is included, so 159 | * downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE) 160 | */ 161 | JDIMENSION downsampled_width; /* actual width in samples */ 162 | JDIMENSION downsampled_height; /* actual height in samples */ 163 | /* This flag is used only for decompression. In cases where some of the 164 | * components will be ignored (eg grayscale output from YCbCr image), 165 | * we can skip most computations for the unused components. 166 | */ 167 | boolean component_needed; /* do we need the value of this component? */ 168 | 169 | /* These values are computed before starting a scan of the component. */ 170 | /* The decompressor output side may not use these variables. */ 171 | int MCU_width; /* number of blocks per MCU, horizontally */ 172 | int MCU_height; /* number of blocks per MCU, vertically */ 173 | int MCU_blocks; /* MCU_width * MCU_height */ 174 | int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */ 175 | int last_col_width; /* # of non-dummy blocks across in last MCU */ 176 | int last_row_height; /* # of non-dummy blocks down in last MCU */ 177 | 178 | /* Saved quantization table for component; NULL if none yet saved. 179 | * See jdinput.c comments about the need for this information. 180 | * This field is currently used only for decompression. 181 | */ 182 | JQUANT_TBL * quant_table; 183 | 184 | /* Private per-component storage for DCT or IDCT subsystem. */ 185 | void * dct_table; 186 | } jpeg_component_info; 187 | 188 | 189 | /* The script for encoding a multiple-scan file is an array of these: */ 190 | 191 | typedef struct { 192 | int comps_in_scan; /* number of components encoded in this scan */ 193 | int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ 194 | int Ss, Se; /* progressive JPEG spectral selection parms */ 195 | int Ah, Al; /* progressive JPEG successive approx. parms */ 196 | } jpeg_scan_info; 197 | 198 | /* The decompressor can save APPn and COM markers in a list of these: */ 199 | 200 | typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; 201 | 202 | struct jpeg_marker_struct { 203 | jpeg_saved_marker_ptr next; /* next in list, or NULL */ 204 | UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ 205 | unsigned int original_length; /* # bytes of data in the file */ 206 | unsigned int data_length; /* # bytes of data saved at data[] */ 207 | JOCTET FAR * data; /* the data contained in the marker */ 208 | /* the marker length word is not counted in data_length or original_length */ 209 | }; 210 | 211 | /* Known color spaces. */ 212 | 213 | #define JCS_EXTENSIONS 1 214 | #define JCS_ALPHA_EXTENSIONS 1 215 | 216 | typedef enum { 217 | JCS_UNKNOWN, /* error/unspecified */ 218 | JCS_GRAYSCALE, /* monochrome */ 219 | JCS_RGB, /* red/green/blue as specified by the RGB_RED, RGB_GREEN, 220 | RGB_BLUE, and RGB_PIXELSIZE macros */ 221 | JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ 222 | JCS_CMYK, /* C/M/Y/K */ 223 | JCS_YCCK, /* Y/Cb/Cr/K */ 224 | JCS_EXT_RGB, /* red/green/blue */ 225 | JCS_EXT_RGBX, /* red/green/blue/x */ 226 | JCS_EXT_BGR, /* blue/green/red */ 227 | JCS_EXT_BGRX, /* blue/green/red/x */ 228 | JCS_EXT_XBGR, /* x/blue/green/red */ 229 | JCS_EXT_XRGB, /* x/red/green/blue */ 230 | /* When out_color_space it set to JCS_EXT_RGBX, JCS_EXT_BGRX, 231 | JCS_EXT_XBGR, or JCS_EXT_XRGB during decompression, the X byte is 232 | undefined, and in order to ensure the best performance, 233 | libjpeg-turbo can set that byte to whatever value it wishes. Use 234 | the following colorspace constants to ensure that the X byte is set 235 | to 0xFF, so that it can be interpreted as an opaque alpha 236 | channel. */ 237 | JCS_EXT_RGBA, /* red/green/blue/alpha */ 238 | JCS_EXT_BGRA, /* blue/green/red/alpha */ 239 | JCS_EXT_ABGR, /* alpha/blue/green/red */ 240 | JCS_EXT_ARGB /* alpha/red/green/blue */ 241 | } J_COLOR_SPACE; 242 | 243 | /* DCT/IDCT algorithm options. */ 244 | 245 | typedef enum { 246 | JDCT_ISLOW, /* slow but accurate integer algorithm */ 247 | JDCT_IFAST, /* faster, less accurate integer method */ 248 | JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ 249 | } J_DCT_METHOD; 250 | 251 | #ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ 252 | #define JDCT_DEFAULT JDCT_ISLOW 253 | #endif 254 | #ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ 255 | #define JDCT_FASTEST JDCT_IFAST 256 | #endif 257 | 258 | /* Dithering options for decompression. */ 259 | 260 | typedef enum { 261 | JDITHER_NONE, /* no dithering */ 262 | JDITHER_ORDERED, /* simple ordered dither */ 263 | JDITHER_FS /* Floyd-Steinberg error diffusion dither */ 264 | } J_DITHER_MODE; 265 | 266 | 267 | /* Common fields between JPEG compression and decompression master structs. */ 268 | 269 | #define jpeg_common_fields \ 270 | struct jpeg_error_mgr * err; /* Error handler module */\ 271 | struct jpeg_memory_mgr * mem; /* Memory manager module */\ 272 | struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ 273 | void * client_data; /* Available for use by application */\ 274 | boolean is_decompressor; /* So common code can tell which is which */\ 275 | int global_state /* For checking call sequence validity */ 276 | 277 | /* Routines that are to be used by both halves of the library are declared 278 | * to receive a pointer to this structure. There are no actual instances of 279 | * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. 280 | */ 281 | struct jpeg_common_struct { 282 | jpeg_common_fields; /* Fields common to both master struct types */ 283 | /* Additional fields follow in an actual jpeg_compress_struct or 284 | * jpeg_decompress_struct. All three structs must agree on these 285 | * initial fields! (This would be a lot cleaner in C++.) 286 | */ 287 | }; 288 | 289 | typedef struct jpeg_common_struct * j_common_ptr; 290 | typedef struct jpeg_compress_struct * j_compress_ptr; 291 | typedef struct jpeg_decompress_struct * j_decompress_ptr; 292 | 293 | 294 | /* Master record for a compression instance */ 295 | 296 | struct jpeg_compress_struct { 297 | jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ 298 | 299 | /* Destination for compressed data */ 300 | struct jpeg_destination_mgr * dest; 301 | 302 | /* Description of source image --- these fields must be filled in by 303 | * outer application before starting compression. in_color_space must 304 | * be correct before you can even call jpeg_set_defaults(). 305 | */ 306 | 307 | JDIMENSION image_width; /* input image width */ 308 | JDIMENSION image_height; /* input image height */ 309 | int input_components; /* # of color components in input image */ 310 | J_COLOR_SPACE in_color_space; /* colorspace of input image */ 311 | 312 | double input_gamma; /* image gamma of input image */ 313 | 314 | /* Compression parameters --- these fields must be set before calling 315 | * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to 316 | * initialize everything to reasonable defaults, then changing anything 317 | * the application specifically wants to change. That way you won't get 318 | * burnt when new parameters are added. Also note that there are several 319 | * helper routines to simplify changing parameters. 320 | */ 321 | 322 | #if JPEG_LIB_VERSION >= 70 323 | unsigned int scale_num, scale_denom; /* fraction by which to scale image */ 324 | 325 | JDIMENSION jpeg_width; /* scaled JPEG image width */ 326 | JDIMENSION jpeg_height; /* scaled JPEG image height */ 327 | /* Dimensions of actual JPEG image that will be written to file, 328 | * derived from input dimensions by scaling factors above. 329 | * These fields are computed by jpeg_start_compress(). 330 | * You can also use jpeg_calc_jpeg_dimensions() to determine these values 331 | * in advance of calling jpeg_start_compress(). 332 | */ 333 | #endif 334 | 335 | int data_precision; /* bits of precision in image data */ 336 | 337 | int num_components; /* # of color components in JPEG image */ 338 | J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ 339 | 340 | jpeg_component_info * comp_info; 341 | /* comp_info[i] describes component that appears i'th in SOF */ 342 | 343 | JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; 344 | #if JPEG_LIB_VERSION >= 70 345 | int q_scale_factor[NUM_QUANT_TBLS]; 346 | #endif 347 | /* ptrs to coefficient quantization tables, or NULL if not defined, 348 | * and corresponding scale factors (percentage, initialized 100). 349 | */ 350 | 351 | JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; 352 | JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; 353 | /* ptrs to Huffman coding tables, or NULL if not defined */ 354 | 355 | UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ 356 | UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ 357 | UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ 358 | 359 | int num_scans; /* # of entries in scan_info array */ 360 | const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ 361 | /* The default value of scan_info is NULL, which causes a single-scan 362 | * sequential JPEG file to be emitted. To create a multi-scan file, 363 | * set num_scans and scan_info to point to an array of scan definitions. 364 | */ 365 | 366 | boolean raw_data_in; /* TRUE=caller supplies downsampled data */ 367 | boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ 368 | boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ 369 | boolean CCIR601_sampling; /* TRUE=first samples are cosited */ 370 | #if JPEG_LIB_VERSION >= 70 371 | boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */ 372 | #endif 373 | int smoothing_factor; /* 1..100, or 0 for no input smoothing */ 374 | J_DCT_METHOD dct_method; /* DCT algorithm selector */ 375 | 376 | /* The restart interval can be specified in absolute MCUs by setting 377 | * restart_interval, or in MCU rows by setting restart_in_rows 378 | * (in which case the correct restart_interval will be figured 379 | * for each scan). 380 | */ 381 | unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ 382 | int restart_in_rows; /* if > 0, MCU rows per restart interval */ 383 | 384 | /* Parameters controlling emission of special markers. */ 385 | 386 | boolean write_JFIF_header; /* should a JFIF marker be written? */ 387 | UINT8 JFIF_major_version; /* What to write for the JFIF version number */ 388 | UINT8 JFIF_minor_version; 389 | /* These three values are not used by the JPEG code, merely copied */ 390 | /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ 391 | /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ 392 | /* ratio is defined by X_density/Y_density even when density_unit=0. */ 393 | UINT8 density_unit; /* JFIF code for pixel size units */ 394 | UINT16 X_density; /* Horizontal pixel density */ 395 | UINT16 Y_density; /* Vertical pixel density */ 396 | boolean write_Adobe_marker; /* should an Adobe marker be written? */ 397 | 398 | /* State variable: index of next scanline to be written to 399 | * jpeg_write_scanlines(). Application may use this to control its 400 | * processing loop, e.g., "while (next_scanline < image_height)". 401 | */ 402 | 403 | JDIMENSION next_scanline; /* 0 .. image_height-1 */ 404 | 405 | /* Remaining fields are known throughout compressor, but generally 406 | * should not be touched by a surrounding application. 407 | */ 408 | 409 | /* 410 | * These fields are computed during compression startup 411 | */ 412 | boolean progressive_mode; /* TRUE if scan script uses progressive mode */ 413 | int max_h_samp_factor; /* largest h_samp_factor */ 414 | int max_v_samp_factor; /* largest v_samp_factor */ 415 | 416 | #if JPEG_LIB_VERSION >= 70 417 | int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ 418 | int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ 419 | #endif 420 | 421 | JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ 422 | /* The coefficient controller receives data in units of MCU rows as defined 423 | * for fully interleaved scans (whether the JPEG file is interleaved or not). 424 | * There are v_samp_factor * DCTSIZE sample rows of each component in an 425 | * "iMCU" (interleaved MCU) row. 426 | */ 427 | 428 | /* 429 | * These fields are valid during any one scan. 430 | * They describe the components and MCUs actually appearing in the scan. 431 | */ 432 | int comps_in_scan; /* # of JPEG components in this scan */ 433 | jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; 434 | /* *cur_comp_info[i] describes component that appears i'th in SOS */ 435 | 436 | JDIMENSION MCUs_per_row; /* # of MCUs across the image */ 437 | JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ 438 | 439 | int blocks_in_MCU; /* # of DCT blocks per MCU */ 440 | int MCU_membership[C_MAX_BLOCKS_IN_MCU]; 441 | /* MCU_membership[i] is index in cur_comp_info of component owning */ 442 | /* i'th block in an MCU */ 443 | 444 | int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ 445 | 446 | #if JPEG_LIB_VERSION >= 80 447 | int block_size; /* the basic DCT block size: 1..16 */ 448 | const int * natural_order; /* natural-order position array */ 449 | int lim_Se; /* min( Se, DCTSIZE2-1 ) */ 450 | #endif 451 | 452 | /* 453 | * Links to compression subobjects (methods and private variables of modules) 454 | */ 455 | struct jpeg_comp_master * master; 456 | struct jpeg_c_main_controller * main; 457 | struct jpeg_c_prep_controller * prep; 458 | struct jpeg_c_coef_controller * coef; 459 | struct jpeg_marker_writer * marker; 460 | struct jpeg_color_converter * cconvert; 461 | struct jpeg_downsampler * downsample; 462 | struct jpeg_forward_dct * fdct; 463 | struct jpeg_entropy_encoder * entropy; 464 | jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ 465 | int script_space_size; 466 | }; 467 | 468 | 469 | /* Master record for a decompression instance */ 470 | 471 | struct jpeg_decompress_struct { 472 | jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ 473 | 474 | /* Source of compressed data */ 475 | struct jpeg_source_mgr * src; 476 | 477 | /* Basic description of image --- filled in by jpeg_read_header(). */ 478 | /* Application may inspect these values to decide how to process image. */ 479 | 480 | JDIMENSION image_width; /* nominal image width (from SOF marker) */ 481 | JDIMENSION image_height; /* nominal image height */ 482 | int num_components; /* # of color components in JPEG image */ 483 | J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ 484 | 485 | /* Decompression processing parameters --- these fields must be set before 486 | * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes 487 | * them to default values. 488 | */ 489 | 490 | J_COLOR_SPACE out_color_space; /* colorspace for output */ 491 | 492 | unsigned int scale_num, scale_denom; /* fraction by which to scale image */ 493 | 494 | double output_gamma; /* image gamma wanted in output */ 495 | 496 | boolean buffered_image; /* TRUE=multiple output passes */ 497 | boolean raw_data_out; /* TRUE=downsampled data wanted */ 498 | 499 | J_DCT_METHOD dct_method; /* IDCT algorithm selector */ 500 | boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ 501 | boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ 502 | 503 | boolean quantize_colors; /* TRUE=colormapped output wanted */ 504 | /* the following are ignored if not quantize_colors: */ 505 | J_DITHER_MODE dither_mode; /* type of color dithering to use */ 506 | boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ 507 | int desired_number_of_colors; /* max # colors to use in created colormap */ 508 | /* these are significant only in buffered-image mode: */ 509 | boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ 510 | boolean enable_external_quant;/* enable future use of external colormap */ 511 | boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ 512 | 513 | /* Description of actual output image that will be returned to application. 514 | * These fields are computed by jpeg_start_decompress(). 515 | * You can also use jpeg_calc_output_dimensions() to determine these values 516 | * in advance of calling jpeg_start_decompress(). 517 | */ 518 | 519 | JDIMENSION output_width; /* scaled image width */ 520 | JDIMENSION output_height; /* scaled image height */ 521 | int out_color_components; /* # of color components in out_color_space */ 522 | int output_components; /* # of color components returned */ 523 | /* output_components is 1 (a colormap index) when quantizing colors; 524 | * otherwise it equals out_color_components. 525 | */ 526 | int rec_outbuf_height; /* min recommended height of scanline buffer */ 527 | /* If the buffer passed to jpeg_read_scanlines() is less than this many rows 528 | * high, space and time will be wasted due to unnecessary data copying. 529 | * Usually rec_outbuf_height will be 1 or 2, at most 4. 530 | */ 531 | 532 | /* When quantizing colors, the output colormap is described by these fields. 533 | * The application can supply a colormap by setting colormap non-NULL before 534 | * calling jpeg_start_decompress; otherwise a colormap is created during 535 | * jpeg_start_decompress or jpeg_start_output. 536 | * The map has out_color_components rows and actual_number_of_colors columns. 537 | */ 538 | int actual_number_of_colors; /* number of entries in use */ 539 | JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ 540 | 541 | /* State variables: these variables indicate the progress of decompression. 542 | * The application may examine these but must not modify them. 543 | */ 544 | 545 | /* Row index of next scanline to be read from jpeg_read_scanlines(). 546 | * Application may use this to control its processing loop, e.g., 547 | * "while (output_scanline < output_height)". 548 | */ 549 | JDIMENSION output_scanline; /* 0 .. output_height-1 */ 550 | 551 | /* Current input scan number and number of iMCU rows completed in scan. 552 | * These indicate the progress of the decompressor input side. 553 | */ 554 | int input_scan_number; /* Number of SOS markers seen so far */ 555 | JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ 556 | 557 | /* The "output scan number" is the notional scan being displayed by the 558 | * output side. The decompressor will not allow output scan/row number 559 | * to get ahead of input scan/row, but it can fall arbitrarily far behind. 560 | */ 561 | int output_scan_number; /* Nominal scan number being displayed */ 562 | JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ 563 | 564 | /* Current progression status. coef_bits[c][i] indicates the precision 565 | * with which component c's DCT coefficient i (in zigzag order) is known. 566 | * It is -1 when no data has yet been received, otherwise it is the point 567 | * transform (shift) value for the most recent scan of the coefficient 568 | * (thus, 0 at completion of the progression). 569 | * This pointer is NULL when reading a non-progressive file. 570 | */ 571 | int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ 572 | 573 | /* Internal JPEG parameters --- the application usually need not look at 574 | * these fields. Note that the decompressor output side may not use 575 | * any parameters that can change between scans. 576 | */ 577 | 578 | /* Quantization and Huffman tables are carried forward across input 579 | * datastreams when processing abbreviated JPEG datastreams. 580 | */ 581 | 582 | JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; 583 | /* ptrs to coefficient quantization tables, or NULL if not defined */ 584 | 585 | JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; 586 | JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; 587 | /* ptrs to Huffman coding tables, or NULL if not defined */ 588 | 589 | /* These parameters are never carried across datastreams, since they 590 | * are given in SOF/SOS markers or defined to be reset by SOI. 591 | */ 592 | 593 | int data_precision; /* bits of precision in image data */ 594 | 595 | jpeg_component_info * comp_info; 596 | /* comp_info[i] describes component that appears i'th in SOF */ 597 | 598 | #if JPEG_LIB_VERSION >= 80 599 | boolean is_baseline; /* TRUE if Baseline SOF0 encountered */ 600 | #endif 601 | boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ 602 | boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ 603 | 604 | UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ 605 | UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ 606 | UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ 607 | 608 | unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ 609 | 610 | /* These fields record data obtained from optional markers recognized by 611 | * the JPEG library. 612 | */ 613 | boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ 614 | /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ 615 | UINT8 JFIF_major_version; /* JFIF version number */ 616 | UINT8 JFIF_minor_version; 617 | UINT8 density_unit; /* JFIF code for pixel size units */ 618 | UINT16 X_density; /* Horizontal pixel density */ 619 | UINT16 Y_density; /* Vertical pixel density */ 620 | boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ 621 | UINT8 Adobe_transform; /* Color transform code from Adobe marker */ 622 | 623 | boolean CCIR601_sampling; /* TRUE=first samples are cosited */ 624 | 625 | /* Aside from the specific data retained from APPn markers known to the 626 | * library, the uninterpreted contents of any or all APPn and COM markers 627 | * can be saved in a list for examination by the application. 628 | */ 629 | jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ 630 | 631 | /* Remaining fields are known throughout decompressor, but generally 632 | * should not be touched by a surrounding application. 633 | */ 634 | 635 | /* 636 | * These fields are computed during decompression startup 637 | */ 638 | int max_h_samp_factor; /* largest h_samp_factor */ 639 | int max_v_samp_factor; /* largest v_samp_factor */ 640 | 641 | #if JPEG_LIB_VERSION >= 70 642 | int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ 643 | int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ 644 | #else 645 | int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ 646 | #endif 647 | 648 | JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ 649 | /* The coefficient controller's input and output progress is measured in 650 | * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows 651 | * in fully interleaved JPEG scans, but are used whether the scan is 652 | * interleaved or not. We define an iMCU row as v_samp_factor DCT block 653 | * rows of each component. Therefore, the IDCT output contains 654 | * v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row. 655 | */ 656 | 657 | JSAMPLE * sample_range_limit; /* table for fast range-limiting */ 658 | 659 | /* 660 | * These fields are valid during any one scan. 661 | * They describe the components and MCUs actually appearing in the scan. 662 | * Note that the decompressor output side must not use these fields. 663 | */ 664 | int comps_in_scan; /* # of JPEG components in this scan */ 665 | jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; 666 | /* *cur_comp_info[i] describes component that appears i'th in SOS */ 667 | 668 | JDIMENSION MCUs_per_row; /* # of MCUs across the image */ 669 | JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ 670 | 671 | int blocks_in_MCU; /* # of DCT blocks per MCU */ 672 | int MCU_membership[D_MAX_BLOCKS_IN_MCU]; 673 | /* MCU_membership[i] is index in cur_comp_info of component owning */ 674 | /* i'th block in an MCU */ 675 | 676 | int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ 677 | 678 | #if JPEG_LIB_VERSION >= 80 679 | /* These fields are derived from Se of first SOS marker. 680 | */ 681 | int block_size; /* the basic DCT block size: 1..16 */ 682 | const int * natural_order; /* natural-order position array for entropy decode */ 683 | int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */ 684 | #endif 685 | 686 | /* This field is shared between entropy decoder and marker parser. 687 | * It is either zero or the code of a JPEG marker that has been 688 | * read from the data source, but has not yet been processed. 689 | */ 690 | int unread_marker; 691 | 692 | /* 693 | * Links to decompression subobjects (methods, private variables of modules) 694 | */ 695 | struct jpeg_decomp_master * master; 696 | struct jpeg_d_main_controller * main; 697 | struct jpeg_d_coef_controller * coef; 698 | struct jpeg_d_post_controller * post; 699 | struct jpeg_input_controller * inputctl; 700 | struct jpeg_marker_reader * marker; 701 | struct jpeg_entropy_decoder * entropy; 702 | struct jpeg_inverse_dct * idct; 703 | struct jpeg_upsampler * upsample; 704 | struct jpeg_color_deconverter * cconvert; 705 | struct jpeg_color_quantizer * cquantize; 706 | }; 707 | 708 | 709 | /* "Object" declarations for JPEG modules that may be supplied or called 710 | * directly by the surrounding application. 711 | * As with all objects in the JPEG library, these structs only define the 712 | * publicly visible methods and state variables of a module. Additional 713 | * private fields may exist after the public ones. 714 | */ 715 | 716 | 717 | /* Error handler object */ 718 | 719 | struct jpeg_error_mgr { 720 | /* Error exit handler: does not return to caller */ 721 | JMETHOD(void, error_exit, (j_common_ptr cinfo)); 722 | /* Conditionally emit a trace or warning message */ 723 | JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); 724 | /* Routine that actually outputs a trace or error message */ 725 | JMETHOD(void, output_message, (j_common_ptr cinfo)); 726 | /* Format a message string for the most recent JPEG error or message */ 727 | JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); 728 | #define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ 729 | /* Reset error state variables at start of a new image */ 730 | JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); 731 | 732 | /* The message ID code and any parameters are saved here. 733 | * A message can have one string parameter or up to 8 int parameters. 734 | */ 735 | int msg_code; 736 | #define JMSG_STR_PARM_MAX 80 737 | union { 738 | int i[8]; 739 | char s[JMSG_STR_PARM_MAX]; 740 | } msg_parm; 741 | 742 | /* Standard state variables for error facility */ 743 | 744 | int trace_level; /* max msg_level that will be displayed */ 745 | 746 | /* For recoverable corrupt-data errors, we emit a warning message, 747 | * but keep going unless emit_message chooses to abort. emit_message 748 | * should count warnings in num_warnings. The surrounding application 749 | * can check for bad data by seeing if num_warnings is nonzero at the 750 | * end of processing. 751 | */ 752 | long num_warnings; /* number of corrupt-data warnings */ 753 | 754 | /* These fields point to the table(s) of error message strings. 755 | * An application can change the table pointer to switch to a different 756 | * message list (typically, to change the language in which errors are 757 | * reported). Some applications may wish to add additional error codes 758 | * that will be handled by the JPEG library error mechanism; the second 759 | * table pointer is used for this purpose. 760 | * 761 | * First table includes all errors generated by JPEG library itself. 762 | * Error code 0 is reserved for a "no such error string" message. 763 | */ 764 | const char * const * jpeg_message_table; /* Library errors */ 765 | int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ 766 | /* Second table can be added by application (see cjpeg/djpeg for example). 767 | * It contains strings numbered first_addon_message..last_addon_message. 768 | */ 769 | const char * const * addon_message_table; /* Non-library errors */ 770 | int first_addon_message; /* code for first string in addon table */ 771 | int last_addon_message; /* code for last string in addon table */ 772 | }; 773 | 774 | 775 | /* Progress monitor object */ 776 | 777 | struct jpeg_progress_mgr { 778 | JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); 779 | 780 | long pass_counter; /* work units completed in this pass */ 781 | long pass_limit; /* total number of work units in this pass */ 782 | int completed_passes; /* passes completed so far */ 783 | int total_passes; /* total number of passes expected */ 784 | }; 785 | 786 | 787 | /* Data destination object for compression */ 788 | 789 | struct jpeg_destination_mgr { 790 | JOCTET * next_output_byte; /* => next byte to write in buffer */ 791 | size_t free_in_buffer; /* # of byte spaces remaining in buffer */ 792 | 793 | JMETHOD(void, init_destination, (j_compress_ptr cinfo)); 794 | JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); 795 | JMETHOD(void, term_destination, (j_compress_ptr cinfo)); 796 | }; 797 | 798 | 799 | /* Data source object for decompression */ 800 | 801 | struct jpeg_source_mgr { 802 | const JOCTET * next_input_byte; /* => next byte to read from buffer */ 803 | size_t bytes_in_buffer; /* # of bytes remaining in buffer */ 804 | 805 | JMETHOD(void, init_source, (j_decompress_ptr cinfo)); 806 | JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); 807 | JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); 808 | JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); 809 | JMETHOD(void, term_source, (j_decompress_ptr cinfo)); 810 | }; 811 | 812 | 813 | /* Memory manager object. 814 | * Allocates "small" objects (a few K total), "large" objects (tens of K), 815 | * and "really big" objects (virtual arrays with backing store if needed). 816 | * The memory manager does not allow individual objects to be freed; rather, 817 | * each created object is assigned to a pool, and whole pools can be freed 818 | * at once. This is faster and more convenient than remembering exactly what 819 | * to free, especially where malloc()/free() are not too speedy. 820 | * NB: alloc routines never return NULL. They exit to error_exit if not 821 | * successful. 822 | */ 823 | 824 | #define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ 825 | #define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ 826 | #define JPOOL_NUMPOOLS 2 827 | 828 | typedef struct jvirt_sarray_control * jvirt_sarray_ptr; 829 | typedef struct jvirt_barray_control * jvirt_barray_ptr; 830 | 831 | 832 | struct jpeg_memory_mgr { 833 | /* Method pointers */ 834 | JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, 835 | size_t sizeofobject)); 836 | JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, 837 | size_t sizeofobject)); 838 | JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, 839 | JDIMENSION samplesperrow, 840 | JDIMENSION numrows)); 841 | JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, 842 | JDIMENSION blocksperrow, 843 | JDIMENSION numrows)); 844 | JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, 845 | int pool_id, 846 | boolean pre_zero, 847 | JDIMENSION samplesperrow, 848 | JDIMENSION numrows, 849 | JDIMENSION maxaccess)); 850 | JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, 851 | int pool_id, 852 | boolean pre_zero, 853 | JDIMENSION blocksperrow, 854 | JDIMENSION numrows, 855 | JDIMENSION maxaccess)); 856 | JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); 857 | JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, 858 | jvirt_sarray_ptr ptr, 859 | JDIMENSION start_row, 860 | JDIMENSION num_rows, 861 | boolean writable)); 862 | JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, 863 | jvirt_barray_ptr ptr, 864 | JDIMENSION start_row, 865 | JDIMENSION num_rows, 866 | boolean writable)); 867 | JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); 868 | JMETHOD(void, self_destruct, (j_common_ptr cinfo)); 869 | 870 | /* Limit on memory allocation for this JPEG object. (Note that this is 871 | * merely advisory, not a guaranteed maximum; it only affects the space 872 | * used for virtual-array buffers.) May be changed by outer application 873 | * after creating the JPEG object. 874 | */ 875 | long max_memory_to_use; 876 | 877 | /* Maximum allocation request accepted by alloc_large. */ 878 | long max_alloc_chunk; 879 | }; 880 | 881 | 882 | /* Routine signature for application-supplied marker processing methods. 883 | * Need not pass marker code since it is stored in cinfo->unread_marker. 884 | */ 885 | typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); 886 | 887 | 888 | /* Declarations for routines called by application. 889 | * The JPP macro hides prototype parameters from compilers that can't cope. 890 | * Note JPP requires double parentheses. 891 | */ 892 | 893 | #ifdef HAVE_PROTOTYPES 894 | #define JPP(arglist) arglist 895 | #else 896 | #define JPP(arglist) () 897 | #endif 898 | 899 | 900 | /* Short forms of external names for systems with brain-damaged linkers. 901 | * We shorten external names to be unique in the first six letters, which 902 | * is good enough for all known systems. 903 | * (If your compiler itself needs names to be unique in less than 15 904 | * characters, you are out of luck. Get a better compiler.) 905 | */ 906 | 907 | #ifdef NEED_SHORT_EXTERNAL_NAMES 908 | #define jpeg_std_error jStdError 909 | #define jpeg_CreateCompress jCreaCompress 910 | #define jpeg_CreateDecompress jCreaDecompress 911 | #define jpeg_destroy_compress jDestCompress 912 | #define jpeg_destroy_decompress jDestDecompress 913 | #define jpeg_stdio_dest jStdDest 914 | #define jpeg_stdio_src jStdSrc 915 | #if JPEG_LIB_VERSION >= 80 916 | #define jpeg_mem_dest jMemDest 917 | #define jpeg_mem_src jMemSrc 918 | #endif 919 | #define jpeg_set_defaults jSetDefaults 920 | #define jpeg_set_colorspace jSetColorspace 921 | #define jpeg_default_colorspace jDefColorspace 922 | #define jpeg_set_quality jSetQuality 923 | #define jpeg_set_linear_quality jSetLQuality 924 | #if JPEG_LIB_VERSION >= 70 925 | #define jpeg_default_qtables jDefQTables 926 | #endif 927 | #define jpeg_add_quant_table jAddQuantTable 928 | #define jpeg_quality_scaling jQualityScaling 929 | #define jpeg_simple_progression jSimProgress 930 | #define jpeg_suppress_tables jSuppressTables 931 | #define jpeg_alloc_quant_table jAlcQTable 932 | #define jpeg_alloc_huff_table jAlcHTable 933 | #define jpeg_start_compress jStrtCompress 934 | #define jpeg_write_scanlines jWrtScanlines 935 | #define jpeg_finish_compress jFinCompress 936 | #if JPEG_LIB_VERSION >= 70 937 | #define jpeg_calc_jpeg_dimensions jCjpegDimensions 938 | #endif 939 | #define jpeg_write_raw_data jWrtRawData 940 | #define jpeg_write_marker jWrtMarker 941 | #define jpeg_write_m_header jWrtMHeader 942 | #define jpeg_write_m_byte jWrtMByte 943 | #define jpeg_write_tables jWrtTables 944 | #define jpeg_read_header jReadHeader 945 | #define jpeg_start_decompress jStrtDecompress 946 | #define jpeg_read_scanlines jReadScanlines 947 | #define jpeg_finish_decompress jFinDecompress 948 | #define jpeg_read_raw_data jReadRawData 949 | #define jpeg_has_multiple_scans jHasMultScn 950 | #define jpeg_start_output jStrtOutput 951 | #define jpeg_finish_output jFinOutput 952 | #define jpeg_input_complete jInComplete 953 | #define jpeg_new_colormap jNewCMap 954 | #define jpeg_consume_input jConsumeInput 955 | #if JPEG_LIB_VERSION >= 80 956 | #define jpeg_core_output_dimensions jCoreDimensions 957 | #endif 958 | #define jpeg_calc_output_dimensions jCalcDimensions 959 | #define jpeg_save_markers jSaveMarkers 960 | #define jpeg_set_marker_processor jSetMarker 961 | #define jpeg_read_coefficients jReadCoefs 962 | #define jpeg_write_coefficients jWrtCoefs 963 | #define jpeg_copy_critical_parameters jCopyCrit 964 | #define jpeg_abort_compress jAbrtCompress 965 | #define jpeg_abort_decompress jAbrtDecompress 966 | #define jpeg_abort jAbort 967 | #define jpeg_destroy jDestroy 968 | #define jpeg_resync_to_restart jResyncRestart 969 | #endif /* NEED_SHORT_EXTERNAL_NAMES */ 970 | 971 | 972 | /* Default error-management setup */ 973 | EXTERN(struct jpeg_error_mgr *) jpeg_std_error 974 | JPP((struct jpeg_error_mgr * err)); 975 | 976 | /* Initialization of JPEG compression objects. 977 | * jpeg_create_compress() and jpeg_create_decompress() are the exported 978 | * names that applications should call. These expand to calls on 979 | * jpeg_CreateCompress and jpeg_CreateDecompress with additional information 980 | * passed for version mismatch checking. 981 | * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. 982 | */ 983 | #define jpeg_create_compress(cinfo) \ 984 | jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ 985 | (size_t) sizeof(struct jpeg_compress_struct)) 986 | #define jpeg_create_decompress(cinfo) \ 987 | jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ 988 | (size_t) sizeof(struct jpeg_decompress_struct)) 989 | EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, 990 | int version, size_t structsize)); 991 | EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, 992 | int version, size_t structsize)); 993 | /* Destruction of JPEG compression objects */ 994 | EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); 995 | EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); 996 | 997 | /* Standard data source and destination managers: stdio streams. */ 998 | /* Caller is responsible for opening the file before and closing after. */ 999 | EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); 1000 | EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); 1001 | 1002 | #if JPEG_LIB_VERSION >= 80 1003 | /* Data source and destination managers: memory buffers. */ 1004 | EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo, 1005 | unsigned char ** outbuffer, 1006 | unsigned long * outsize)); 1007 | EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo, 1008 | unsigned char * inbuffer, 1009 | unsigned long insize)); 1010 | #endif 1011 | 1012 | /* Default parameter setup for compression */ 1013 | EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); 1014 | /* Compression parameter setup aids */ 1015 | EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, 1016 | J_COLOR_SPACE colorspace)); 1017 | EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); 1018 | EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, 1019 | boolean force_baseline)); 1020 | EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, 1021 | int scale_factor, 1022 | boolean force_baseline)); 1023 | #if JPEG_LIB_VERSION >= 70 1024 | EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo, 1025 | boolean force_baseline)); 1026 | #endif 1027 | EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, 1028 | const unsigned int *basic_table, 1029 | int scale_factor, 1030 | boolean force_baseline)); 1031 | EXTERN(int) jpeg_quality_scaling JPP((int quality)); 1032 | EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); 1033 | EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, 1034 | boolean suppress)); 1035 | EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); 1036 | EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); 1037 | 1038 | /* Main entry points for compression */ 1039 | EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, 1040 | boolean write_all_tables)); 1041 | EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, 1042 | JSAMPARRAY scanlines, 1043 | JDIMENSION num_lines)); 1044 | EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); 1045 | 1046 | #if JPEG_LIB_VERSION >= 70 1047 | /* Precalculate JPEG dimensions for current compression parameters. */ 1048 | EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo)); 1049 | #endif 1050 | 1051 | /* Replaces jpeg_write_scanlines when writing raw downsampled data. */ 1052 | EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, 1053 | JSAMPIMAGE data, 1054 | JDIMENSION num_lines)); 1055 | 1056 | /* Write a special marker. See libjpeg.txt concerning safe usage. */ 1057 | EXTERN(void) jpeg_write_marker 1058 | JPP((j_compress_ptr cinfo, int marker, 1059 | const JOCTET * dataptr, unsigned int datalen)); 1060 | /* Same, but piecemeal. */ 1061 | EXTERN(void) jpeg_write_m_header 1062 | JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); 1063 | EXTERN(void) jpeg_write_m_byte 1064 | JPP((j_compress_ptr cinfo, int val)); 1065 | 1066 | /* Alternate compression function: just write an abbreviated table file */ 1067 | EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); 1068 | 1069 | /* Decompression startup: read start of JPEG datastream to see what's there */ 1070 | EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, 1071 | boolean require_image)); 1072 | /* Return value is one of: */ 1073 | #define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ 1074 | #define JPEG_HEADER_OK 1 /* Found valid image datastream */ 1075 | #define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ 1076 | /* If you pass require_image = TRUE (normal case), you need not check for 1077 | * a TABLES_ONLY return code; an abbreviated file will cause an error exit. 1078 | * JPEG_SUSPENDED is only possible if you use a data source module that can 1079 | * give a suspension return (the stdio source module doesn't). 1080 | */ 1081 | 1082 | /* Main entry points for decompression */ 1083 | EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); 1084 | EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, 1085 | JSAMPARRAY scanlines, 1086 | JDIMENSION max_lines)); 1087 | EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); 1088 | 1089 | /* Replaces jpeg_read_scanlines when reading raw downsampled data. */ 1090 | EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, 1091 | JSAMPIMAGE data, 1092 | JDIMENSION max_lines)); 1093 | 1094 | /* Additional entry points for buffered-image mode. */ 1095 | EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); 1096 | EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, 1097 | int scan_number)); 1098 | EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); 1099 | EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); 1100 | EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); 1101 | EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); 1102 | /* Return value is one of: */ 1103 | /* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ 1104 | #define JPEG_REACHED_SOS 1 /* Reached start of new scan */ 1105 | #define JPEG_REACHED_EOI 2 /* Reached end of image */ 1106 | #define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ 1107 | #define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ 1108 | 1109 | /* Precalculate output dimensions for current decompression parameters. */ 1110 | #if JPEG_LIB_VERSION >= 80 1111 | EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo)); 1112 | #endif 1113 | EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); 1114 | 1115 | /* Control saving of COM and APPn markers into marker_list. */ 1116 | EXTERN(void) jpeg_save_markers 1117 | JPP((j_decompress_ptr cinfo, int marker_code, 1118 | unsigned int length_limit)); 1119 | 1120 | /* Install a special processing method for COM or APPn markers. */ 1121 | EXTERN(void) jpeg_set_marker_processor 1122 | JPP((j_decompress_ptr cinfo, int marker_code, 1123 | jpeg_marker_parser_method routine)); 1124 | 1125 | /* Read or write raw DCT coefficients --- useful for lossless transcoding. */ 1126 | EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); 1127 | EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, 1128 | jvirt_barray_ptr * coef_arrays)); 1129 | EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, 1130 | j_compress_ptr dstinfo)); 1131 | 1132 | /* If you choose to abort compression or decompression before completing 1133 | * jpeg_finish_(de)compress, then you need to clean up to release memory, 1134 | * temporary files, etc. You can just call jpeg_destroy_(de)compress 1135 | * if you're done with the JPEG object, but if you want to clean it up and 1136 | * reuse it, call this: 1137 | */ 1138 | EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); 1139 | EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); 1140 | 1141 | /* Generic versions of jpeg_abort and jpeg_destroy that work on either 1142 | * flavor of JPEG object. These may be more convenient in some places. 1143 | */ 1144 | EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); 1145 | EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); 1146 | 1147 | /* Default restart-marker-resync procedure for use by data source modules */ 1148 | EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, 1149 | int desired)); 1150 | 1151 | 1152 | /* These marker codes are exported since applications and data source modules 1153 | * are likely to want to use them. 1154 | */ 1155 | 1156 | #define JPEG_RST0 0xD0 /* RST0 marker code */ 1157 | #define JPEG_EOI 0xD9 /* EOI marker code */ 1158 | #define JPEG_APP0 0xE0 /* APP0 marker code */ 1159 | #define JPEG_COM 0xFE /* COM marker code */ 1160 | 1161 | 1162 | /* If we have a brain-damaged compiler that emits warnings (or worse, errors) 1163 | * for structure definitions that are never filled in, keep it quiet by 1164 | * supplying dummy definitions for the various substructures. 1165 | */ 1166 | 1167 | #ifdef INCOMPLETE_TYPES_BROKEN 1168 | #ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ 1169 | struct jvirt_sarray_control { long dummy; }; 1170 | struct jvirt_barray_control { long dummy; }; 1171 | struct jpeg_comp_master { long dummy; }; 1172 | struct jpeg_c_main_controller { long dummy; }; 1173 | struct jpeg_c_prep_controller { long dummy; }; 1174 | struct jpeg_c_coef_controller { long dummy; }; 1175 | struct jpeg_marker_writer { long dummy; }; 1176 | struct jpeg_color_converter { long dummy; }; 1177 | struct jpeg_downsampler { long dummy; }; 1178 | struct jpeg_forward_dct { long dummy; }; 1179 | struct jpeg_entropy_encoder { long dummy; }; 1180 | struct jpeg_decomp_master { long dummy; }; 1181 | struct jpeg_d_main_controller { long dummy; }; 1182 | struct jpeg_d_coef_controller { long dummy; }; 1183 | struct jpeg_d_post_controller { long dummy; }; 1184 | struct jpeg_input_controller { long dummy; }; 1185 | struct jpeg_marker_reader { long dummy; }; 1186 | struct jpeg_entropy_decoder { long dummy; }; 1187 | struct jpeg_inverse_dct { long dummy; }; 1188 | struct jpeg_upsampler { long dummy; }; 1189 | struct jpeg_color_deconverter { long dummy; }; 1190 | struct jpeg_color_quantizer { long dummy; }; 1191 | #endif /* JPEG_INTERNALS */ 1192 | #endif /* INCOMPLETE_TYPES_BROKEN */ 1193 | 1194 | 1195 | /* 1196 | * The JPEG library modules define JPEG_INTERNALS before including this file. 1197 | * The internal structure declarations are read only when that is true. 1198 | * Applications using the library should not include jpegint.h, but may wish 1199 | * to include jerror.h. 1200 | */ 1201 | 1202 | #ifdef JPEG_INTERNALS 1203 | #include "jpegint.h" /* fetch private declarations */ 1204 | #include "jerror.h" /* fetch error codes too */ 1205 | #endif 1206 | 1207 | #ifdef __cplusplus 1208 | #ifndef DONT_USE_EXTERN_C 1209 | } 1210 | #endif 1211 | #endif 1212 | 1213 | #endif /* JPEGLIB_H */ 1214 | -------------------------------------------------------------------------------- /convert/mjpeg2rgb.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/convert/mjpeg2rgb.c -------------------------------------------------------------------------------- /convert/rgb2rgb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static int isSupportRgb2Rgb(int iPixelFormatIn, int iPixelFormatOut) 6 | { 7 | if (iPixelFormatIn != V4L2_PIX_FMT_RGB565) 8 | return 0; 9 | if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32)) 10 | { 11 | return 0; 12 | } 13 | return 1; 14 | } 15 | 16 | static int Rgb2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut) 17 | { 18 | PT_PixelDatas ptPixelDatasIn = &ptVideoBufIn->tPixelDatas; 19 | PT_PixelDatas ptPixelDatasOut = &ptVideoBufOut->tPixelDatas; 20 | 21 | int x, y; 22 | int r, g, b; 23 | int color; 24 | unsigned short *pwSrc = (unsigned short *)ptPixelDatasIn->aucPixelDatas; 25 | unsigned int *pdwDest; 26 | 27 | if (ptVideoBufIn->iPixelFormat != V4L2_PIX_FMT_RGB565) 28 | { 29 | return -1; 30 | } 31 | 32 | if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB565) 33 | { 34 | ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth; 35 | ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight; 36 | ptPixelDatasOut->iBpp = 16; 37 | ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8; 38 | ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight; 39 | if (!ptPixelDatasOut->aucPixelDatas) 40 | { 41 | ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes); 42 | } 43 | 44 | memcpy(ptPixelDatasOut->aucPixelDatas, ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->iTotalBytes); 45 | return 0; 46 | } 47 | else if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB32) 48 | { 49 | ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth; 50 | ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight; 51 | ptPixelDatasOut->iBpp = 32; 52 | ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8; 53 | ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight; 54 | if (!ptPixelDatasOut->aucPixelDatas) 55 | { 56 | ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes); 57 | } 58 | 59 | pdwDest = (unsigned int *)ptPixelDatasOut->aucPixelDatas; 60 | 61 | for (y = 0; y < ptPixelDatasOut->iHeight; y++) 62 | { 63 | for (x = 0; x < ptPixelDatasOut->iWidth; x++) 64 | { 65 | color = *pwSrc++; 66 | /* 从RGB565 格式中提取 R,G,B */ 67 | r = color >> 11; 68 | g = (color >> 5) & (0x3f); 69 | b = color & 0x1f; 70 | 71 | /* r,g,b转为0x00RRGGBB的32位数据 */ 72 | color = ((r << 3) << 16) | ((g << 2) << 8) | (b << 3); 73 | 74 | *pdwDest = color; 75 | pdwDest++; 76 | } 77 | } 78 | return 0; 79 | } 80 | 81 | return -1; 82 | } 83 | 84 | static int Rgb2RgbConvertExit(PT_VideoBuf ptVideoBufOut) 85 | { 86 | if (ptVideoBufOut->tPixelDatas.aucPixelDatas) 87 | { 88 | free(ptVideoBufOut->tPixelDatas.aucPixelDatas); 89 | ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL; 90 | } 91 | return 0; 92 | } 93 | 94 | /* */ 95 | static T_VideoConvert g_tRgb2RgbConvert = { 96 | .name = "rgb2rgb", 97 | .isSupport = isSupportRgb2Rgb, 98 | .Convert = Rgb2RgbConvert, 99 | .ConvertExit = Rgb2RgbConvertExit, 100 | }; 101 | 102 | 103 | /* 注册函数 */ 104 | int Rgb2RgbInit(void) 105 | { 106 | return RegisterVideoConvert(&g_tRgb2RgbConvert); 107 | } 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /convert/yuv2rgb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "color.h" 4 | 5 | static int isSupportYuv2Rgb(int iPixelFormatIn, int iPixelFormatOut) 6 | { 7 | if (iPixelFormatIn != V4L2_PIX_FMT_YUYV) 8 | return 0; 9 | if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32)) 10 | { 11 | return 0; 12 | } 13 | return 1; 14 | } 15 | 16 | 17 | 18 | /* 将YUV422 数据包转换成 rgb565 */ 19 | 20 | static unsigned int 21 | Pyuv422torgb565(unsigned char * input_ptr, unsigned char * output_ptr, unsigned int image_width, unsigned int image_height) 22 | { 23 | unsigned int i, size; 24 | unsigned char Y, Y1, U, V; 25 | unsigned char *buff = input_ptr; 26 | unsigned char *output_pt = output_ptr; 27 | 28 | unsigned int r, g, b; 29 | unsigned int color; 30 | 31 | size = image_width * image_height /2; 32 | for (i = size; i > 0; i--) { 33 | 34 | Y = buff[0] ; 35 | U = buff[1] ; 36 | Y1 = buff[2]; 37 | V = buff[3]; 38 | buff += 4; 39 | r = R_FROMYV(Y,V); 40 | g = G_FROMYUV(Y,U,V); //b 41 | b = B_FROMYU(Y,U); //v 42 | 43 | /* 将r,g,b 转换为 rgb565ֵ 的16 位值*/ 44 | r = r >> 3; 45 | g = g >> 2; 46 | b = b >> 3; 47 | color = (r << 11) | (g << 5) | b; 48 | *output_pt++ = color & 0xff; 49 | *output_pt++ = (color >> 8) & 0xff; 50 | 51 | r = R_FROMYV(Y1,V); 52 | g = G_FROMYUV(Y1,U,V); //b 53 | b = B_FROMYU(Y1,U); //v 54 | 55 | /* 将r,g,b 转换为 rgb565ֵ 的16 位值*/ 56 | r = r >> 3; 57 | g = g >> 2; 58 | b = b >> 3; 59 | color = (r << 11) | (g << 5) | b; 60 | *output_pt++ = color & 0xff; 61 | *output_pt++ = (color >> 8) & 0xff; 62 | } 63 | 64 | return 0; 65 | } 66 | 67 | 68 | 69 | 70 | /* 将YUV422 数据包转换成 rgb32 */ 71 | 72 | static unsigned int 73 | Pyuv422torgb32(unsigned char * input_ptr, unsigned char * output_ptr, unsigned int image_width, unsigned int image_height) 74 | { 75 | unsigned int i, size; 76 | unsigned char Y, Y1, U, V; 77 | unsigned char *buff = input_ptr; 78 | unsigned int *output_pt = (unsigned int *)output_ptr; 79 | 80 | unsigned int r, g, b; 81 | unsigned int color; 82 | 83 | size = image_width * image_height /2; 84 | for (i = size; i > 0; i--) { 85 | /* bgr instead rgb ?? */ 86 | Y = buff[0] ; 87 | U = buff[1] ; 88 | Y1 = buff[2]; 89 | V = buff[3]; 90 | buff += 4; 91 | 92 | r = R_FROMYV(Y,V); 93 | g = G_FROMYUV(Y,U,V); //b 94 | b = B_FROMYU(Y,U); //v 95 | /* rgb888 */ 96 | color = (r << 16) | (g << 8) | b; 97 | *output_pt++ = color; 98 | 99 | r = R_FROMYV(Y1,V); 100 | g = G_FROMYUV(Y1,U,V); //b 101 | b = B_FROMYU(Y1,U); //v 102 | color = (r << 16) | (g << 8) | b; 103 | *output_pt++ = color; 104 | } 105 | 106 | return 0; 107 | } 108 | 109 | /* 参考 luvcview */ 110 | static int Yuv2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut) 111 | { 112 | PT_PixelDatas ptPixelDatasIn = &ptVideoBufIn->tPixelDatas; 113 | PT_PixelDatas ptPixelDatasOut = &ptVideoBufOut->tPixelDatas; 114 | 115 | ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth; 116 | ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight; 117 | 118 | if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB565) 119 | { 120 | ptPixelDatasOut->iBpp = 16; 121 | ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8; 122 | ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight; 123 | 124 | if (!ptPixelDatasOut->aucPixelDatas) 125 | { 126 | ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes); 127 | } 128 | 129 | Pyuv422torgb565(ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->aucPixelDatas, ptPixelDatasOut->iWidth, ptPixelDatasOut->iHeight); 130 | return 0; 131 | } 132 | else if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB32) 133 | { 134 | ptPixelDatasOut->iBpp = 32; 135 | ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8; 136 | ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight; 137 | 138 | if (!ptPixelDatasOut->aucPixelDatas) 139 | { 140 | ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes); 141 | } 142 | 143 | Pyuv422torgb32(ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->aucPixelDatas, ptPixelDatasOut->iWidth, ptPixelDatasOut->iHeight); 144 | return 0; 145 | } 146 | 147 | return -1; 148 | } 149 | 150 | static int Yuv2RgbConvertExit(PT_VideoBuf ptVideoBufOut) 151 | { 152 | if (ptVideoBufOut->tPixelDatas.aucPixelDatas) 153 | { 154 | free(ptVideoBufOut->tPixelDatas.aucPixelDatas); 155 | ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL; 156 | } 157 | return 0; 158 | } 159 | 160 | /* 构造结构体 */ 161 | static T_VideoConvert g_tYuv2RgbConvert = { 162 | .name = "yuv2rgb", 163 | .isSupport = isSupportYuv2Rgb, 164 | .Convert = Yuv2RgbConvert, 165 | .ConvertExit = Yuv2RgbConvertExit, 166 | }; 167 | 168 | extern void initLut(void); 169 | 170 | /* 注册 */ 171 | int Yuv2RgbInit(void) 172 | { 173 | initLut(); 174 | return RegisterVideoConvert(&g_tYuv2RgbConvert); 175 | } 176 | 177 | -------------------------------------------------------------------------------- /display/Makefile: -------------------------------------------------------------------------------- 1 | obj-y += disp_manager.o 2 | obj-y += fb.o -------------------------------------------------------------------------------- /display/disp_manager.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/display/disp_manager.c -------------------------------------------------------------------------------- /display/fb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int FBDeviceInit(void); 12 | static int FBShowPixel(int iX, int iY, unsigned int dwColor); 13 | static int FBCleanScreen(unsigned int dwBackColor); 14 | static int FBShowPage(PT_PixelDatas ptPixelDatas); 15 | 16 | 17 | static int g_fd; 18 | 19 | 20 | static struct fb_var_screeninfo g_tFBVar; 21 | static struct fb_fix_screeninfo g_tFBFix; 22 | static unsigned char *g_pucFBMem; 23 | static unsigned int g_dwScreenSize; 24 | 25 | static unsigned int g_dwLineWidth; 26 | static unsigned int g_dwPixelWidth; 27 | 28 | static T_DispOpr g_tFBOpr = { 29 | .name = "fb", 30 | .DeviceInit = FBDeviceInit, 31 | .ShowPixel = FBShowPixel, 32 | .CleanScreen = FBCleanScreen, 33 | .ShowPage = FBShowPage, 34 | }; 35 | 36 | /* 显示设备初始化函数 */ 37 | static int FBDeviceInit(void) 38 | { 39 | int ret; 40 | 41 | g_fd = open(FB_DEVICE_NAME, O_RDWR); 42 | if (0 > g_fd) 43 | { 44 | DBG_PRINTF("can't open %s\n", FB_DEVICE_NAME); 45 | } 46 | 47 | ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar); 48 | if (ret < 0) 49 | { 50 | DBG_PRINTF("can't get fb's var\n"); 51 | return -1; 52 | } 53 | 54 | ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix); 55 | if (ret < 0) 56 | { 57 | DBG_PRINTF("can't get fb's fix\n"); 58 | return -1; 59 | } 60 | 61 | g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8; 62 | g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0); 63 | if (0 > g_pucFBMem) 64 | { 65 | DBG_PRINTF("can't mmap\n"); 66 | return -1; 67 | } 68 | 69 | g_tFBOpr.iXres = g_tFBVar.xres; 70 | g_tFBOpr.iYres = g_tFBVar.yres; 71 | g_tFBOpr.iBpp = g_tFBVar.bits_per_pixel; 72 | g_tFBOpr.iLineWidth = g_tFBVar.xres * g_tFBOpr.iBpp / 8; 73 | g_tFBOpr.pucDispMem = g_pucFBMem; 74 | 75 | g_dwLineWidth = g_tFBVar.xres * g_tFBVar.bits_per_pixel / 8; 76 | g_dwPixelWidth = g_tFBVar.bits_per_pixel / 8; 77 | 78 | return 0; 79 | } 80 | 81 | 82 | /* 设置 FrameBuffer 的指定像素为某颜色**/ 83 | static int FBShowPixel(int iX, int iY, unsigned int dwColor) 84 | { 85 | unsigned char *pucFB; 86 | unsigned short *pwFB16bpp; 87 | unsigned int *pdwFB32bpp; 88 | unsigned short wColor16bpp; /* 565 */ 89 | int iRed; 90 | int iGreen; 91 | int iBlue; 92 | 93 | if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres)) 94 | { 95 | DBG_PRINTF("out of region\n"); 96 | return -1; 97 | } 98 | 99 | pucFB = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX; 100 | pwFB16bpp = (unsigned short *)pucFB; 101 | pdwFB32bpp = (unsigned int *)pucFB; 102 | 103 | switch (g_tFBVar.bits_per_pixel) 104 | { 105 | case 8: 106 | { 107 | *pucFB = (unsigned char)dwColor; 108 | break; 109 | } 110 | case 16: 111 | { 112 | /* 从dwBackColor中取出红绿蓝三原色, 113 | * 构造为16Bpp的颜色 114 | */ 115 | iRed = (dwColor >> (16+3)) & 0x1f; 116 | iGreen = (dwColor >> (8+2)) & 0x3f; 117 | iBlue = (dwColor >> 3) & 0x1f; 118 | wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue; 119 | *pwFB16bpp = wColor16bpp; 120 | break; 121 | } 122 | case 32: 123 | { 124 | *pdwFB32bpp = dwColor; 125 | break; 126 | } 127 | default : 128 | { 129 | DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel); 130 | return -1; 131 | } 132 | } 133 | 134 | return 0; 135 | } 136 | 137 | /* 把PT_VideoMem中的颜色数据在FrameBuffer上显示出来 */ 138 | static int FBShowPage(PT_PixelDatas ptPixelDatas) 139 | { 140 | if (g_tFBOpr.pucDispMem != ptPixelDatas->aucPixelDatas) 141 | { 142 | memcpy(g_tFBOpr.pucDispMem, ptPixelDatas->aucPixelDatas, ptPixelDatas->iTotalBytes); 143 | } 144 | return 0; 145 | } 146 | 147 | /* 清屏 **/ 148 | static int FBCleanScreen(unsigned int dwBackColor) 149 | { 150 | unsigned char *pucFB; 151 | unsigned short *pwFB16bpp; 152 | unsigned int *pdwFB32bpp; 153 | unsigned short wColor16bpp; /* 565 */ 154 | int iRed; 155 | int iGreen; 156 | int iBlue; 157 | int i = 0; 158 | 159 | pucFB = g_pucFBMem; 160 | pwFB16bpp = (unsigned short *)pucFB; 161 | pdwFB32bpp = (unsigned int *)pucFB; 162 | 163 | switch (g_tFBVar.bits_per_pixel) 164 | { 165 | case 8: 166 | { 167 | memset(g_pucFBMem, dwBackColor, g_dwScreenSize); 168 | break; 169 | } 170 | case 16: 171 | { 172 | /* 从dwBackColor中取出红绿蓝三原色, 173 | * 构造为16Bpp的颜色 174 | */ 175 | iRed = (dwBackColor >> (16+3)) & 0x1f; 176 | iGreen = (dwBackColor >> (8+2)) & 0x3f; 177 | iBlue = (dwBackColor >> 3) & 0x1f; 178 | wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue; 179 | while (i < g_dwScreenSize) 180 | { 181 | *pwFB16bpp = wColor16bpp; 182 | pwFB16bpp++; 183 | i += 2; 184 | } 185 | break; 186 | } 187 | case 32: 188 | { 189 | while (i < g_dwScreenSize) 190 | { 191 | *pdwFB32bpp = dwBackColor; 192 | pdwFB32bpp++; 193 | i += 4; 194 | } 195 | break; 196 | } 197 | default : 198 | { 199 | DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel); 200 | return -1; 201 | } 202 | } 203 | 204 | return 0; 205 | } 206 | 207 | /* 注册 FrameBuffer 显示设备*/ 208 | int FBInit(void) 209 | { 210 | return RegisterDispOpr(&g_tFBOpr); 211 | } 212 | 213 | -------------------------------------------------------------------------------- /include/config.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _CONFIG_H 3 | #define _CONFIG_H 4 | 5 | #include 6 | 7 | 8 | //#define DBG_PRINTF(...) 9 | #define DBG_PRINTF printf 10 | 11 | #define FB_DEVICE_NAME "/dev/fb0" 12 | 13 | #endif /* _CONFIG_H */ 14 | -------------------------------------------------------------------------------- /include/convert_manager.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _CONVERT_MANAGER_H 3 | #define _CONVERT_MANAGER_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | typedef struct VideoConvert { 10 | char *name; 11 | int (*isSupport)(int iPixelFormatIn, int iPixelFormatOut); 12 | int (*Convert)(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut); 13 | int (*ConvertExit)(PT_VideoBuf ptVideoBufOut); 14 | struct VideoConvert *ptNext; 15 | }T_VideoConvert, *PT_VideoConvert; 16 | 17 | PT_VideoConvert GetVideoConvertForFormats(int iPixelFormatIn, int iPixelFormatOut); 18 | int VideoConvertInit(void); 19 | 20 | int Yuv2RgbInit(void); 21 | int Mjpeg2RgbInit(void); 22 | int Rgb2RgbInit(void); 23 | int RegisterVideoConvert(PT_VideoConvert ptVideoConvert); 24 | 25 | 26 | #endif /* _CONVERT_MANAGER_H */ 27 | 28 | -------------------------------------------------------------------------------- /include/disp_manager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/include/disp_manager.h -------------------------------------------------------------------------------- /include/pic_operation.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/include/pic_operation.h -------------------------------------------------------------------------------- /include/picfmt_manager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/include/picfmt_manager.h -------------------------------------------------------------------------------- /include/render.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/include/render.h -------------------------------------------------------------------------------- /include/video_manager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/include/video_manager.h -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | /*调用方式: video2lcd */ 22 | int main(int argc, char **argv) 23 | { 24 | int iError; 25 | T_VideoDevice tVideoDevice; 26 | PT_VideoConvert ptVideoConvert; 27 | int iPixelFormatOfVideo; 28 | int iPixelFormatOfDisp; 29 | 30 | PT_VideoBuf ptVideoBufCur; 31 | T_VideoBuf tVideoBuf; 32 | T_VideoBuf tConvertBuf; 33 | T_VideoBuf tZoomBuf; 34 | T_VideoBuf tFrameBuf; 35 | 36 | int iLcdWidth; 37 | int iLcdHeigt; 38 | int iLcdBpp; 39 | 40 | int iTopLeftX; 41 | int iTopLeftY; 42 | 43 | float k; 44 | 45 | if (argc != 2) 46 | { 47 | printf("Usage:\n"); 48 | printf("%s \n", argv[0]); 49 | return -1; 50 | } 51 | 52 | 53 | 54 | /* 各种初始化,注册显示设备 */ 55 | DisplayInit(); 56 | /* 支持多个显示设备时: 选择和初始化指定的显示设备*/ 57 | SelectAndInitDefaultDispDev("fb"); 58 | GetDispResolution(&iLcdWidth, &iLcdHeigt, &iLcdBpp); 59 | GetVideoBufForDisplay(&tFrameBuf); 60 | iPixelFormatOfDisp = tFrameBuf.iPixelFormat; 61 | 62 | VideoInit(); 63 | 64 | iError = VideoDeviceInit(argv[1], &tVideoDevice); 65 | if (iError) 66 | { 67 | DBG_PRINTF("VideoDeviceInit for %s error!\n", argv[1]); 68 | return -1; 69 | } 70 | iPixelFormatOfVideo = tVideoDevice.ptOPr->GetFormat(&tVideoDevice); 71 | 72 | VideoConvertInit(); 73 | ptVideoConvert = GetVideoConvertForFormats(iPixelFormatOfVideo, iPixelFormatOfDisp); 74 | if (NULL == ptVideoConvert) 75 | { 76 | DBG_PRINTF("can not support this format convert\n"); 77 | return -1; 78 | } 79 | 80 | 81 | /* 启动摄像头设备 */ 82 | iError = tVideoDevice.ptOPr->StartDevice(&tVideoDevice); 83 | if (iError) 84 | { 85 | DBG_PRINTF("StartDevice for %s error!\n", argv[1]); 86 | return -1; 87 | } 88 | 89 | memset(&tVideoBuf, 0, sizeof(tVideoBuf)); 90 | memset(&tConvertBuf, 0, sizeof(tConvertBuf)); 91 | tConvertBuf.iPixelFormat = iPixelFormatOfDisp; 92 | tConvertBuf.tPixelDatas.iBpp = iLcdBpp; 93 | 94 | 95 | memset(&tZoomBuf, 0, sizeof(tZoomBuf)); 96 | 97 | 98 | while (1) 99 | { 100 | /* 读入摄像头数据*/ 101 | iError = tVideoDevice.ptOPr->GetFrame(&tVideoDevice, &tVideoBuf); 102 | if (iError) 103 | { 104 | DBG_PRINTF("GetFrame for %s error!\n", argv[1]); 105 | return -1; 106 | } 107 | ptVideoBufCur = &tVideoBuf; 108 | 109 | if (iPixelFormatOfVideo != iPixelFormatOfDisp) 110 | { 111 | /* 将数据转换为 RGB 格式 */ 112 | iError = ptVideoConvert->Convert(&tVideoBuf, &tConvertBuf); 113 | DBG_PRINTF("Convert %s, ret = %d\n", ptVideoConvert->name, iError); 114 | if (iError) 115 | { 116 | DBG_PRINTF("Convert for %s error!\n", argv[1]); 117 | return -1; 118 | } 119 | ptVideoBufCur = &tConvertBuf; 120 | } 121 | 122 | 123 | /*如果图像分辨率大于 LCD,则缩放 */ 124 | if (ptVideoBufCur->tPixelDatas.iWidth > iLcdWidth || ptVideoBufCur->tPixelDatas.iHeight > iLcdHeigt) 125 | { 126 | /* 确定缩放后的分辨率 */ 127 | /* 把图片按比例缩放到VideoMem上, 居中显示 128 | * 算出缩放后的大小 129 | */ 130 | k = (float)ptVideoBufCur->tPixelDatas.iHeight / ptVideoBufCur->tPixelDatas.iWidth; 131 | tZoomBuf.tPixelDatas.iWidth = iLcdWidth; 132 | tZoomBuf.tPixelDatas.iHeight = iLcdWidth * k; 133 | if ( tZoomBuf.tPixelDatas.iHeight > iLcdHeigt) 134 | { 135 | tZoomBuf.tPixelDatas.iWidth = iLcdHeigt / k; 136 | tZoomBuf.tPixelDatas.iHeight = iLcdHeigt; 137 | } 138 | tZoomBuf.tPixelDatas.iBpp = iLcdBpp; 139 | tZoomBuf.tPixelDatas.iLineBytes = tZoomBuf.tPixelDatas.iWidth * tZoomBuf.tPixelDatas.iBpp / 8; 140 | tZoomBuf.tPixelDatas.iTotalBytes = tZoomBuf.tPixelDatas.iLineBytes * tZoomBuf.tPixelDatas.iHeight; 141 | 142 | if (!tZoomBuf.tPixelDatas.aucPixelDatas) 143 | { 144 | tZoomBuf.tPixelDatas.aucPixelDatas = malloc(tZoomBuf.tPixelDatas.iTotalBytes); 145 | } 146 | 147 | PicZoom(&ptVideoBufCur->tPixelDatas, &tZoomBuf.tPixelDatas); 148 | ptVideoBufCur = &tZoomBuf; 149 | } 150 | 151 | /* 合并进framebuffer */ 152 | /* 接着算出居中显示时左上角坐标 */ 153 | iTopLeftX = (iLcdWidth - ptVideoBufCur->tPixelDatas.iWidth) / 2; 154 | iTopLeftY = (iLcdHeigt - ptVideoBufCur->tPixelDatas.iHeight) / 2; 155 | 156 | PicMerge(iTopLeftX, iTopLeftY, &ptVideoBufCur->tPixelDatas, &tFrameBuf.tPixelDatas); 157 | 158 | FlushPixelDatasToDev(&tFrameBuf.tPixelDatas); 159 | 160 | iError = tVideoDevice.ptOPr->PutFrame(&tVideoDevice, &tVideoBuf); 161 | if (iError) 162 | { 163 | DBG_PRINTF("PutFrame for %s error!\n", argv[1]); 164 | return -1; 165 | } 166 | 167 | /* 把framebuffer的数据刷到LCD上, 显示 */ 168 | } 169 | 170 | return 0; 171 | } 172 | 173 | -------------------------------------------------------------------------------- /myuvc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/myuvc.c -------------------------------------------------------------------------------- /netprint_client.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/netprint_client.c -------------------------------------------------------------------------------- /qt_source/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /qt_source/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | void MainWindow::iniCamera() 9 | {// 创建 QCamera对象 10 | } 11 | 12 | void MainWindow::iniImageCapture() 13 | {//创建 QCameraImageCapture对象 14 | } 15 | 16 | void MainWindow::iniVideoRecorder() 17 | {//创建QMediaRecorder对象 18 | } 19 | 20 | void MainWindow::showCameraDeviceInfo(QCameraDevice *device) 21 | {//显示摄像头设备信息 22 | ui->comboCam_Position->setCurrentIndex(device->position()); //摄像头位置 23 | 24 | ui->comboCam_PhotoRes->clear(); //支持的拍照分辨率 25 | ui->comboImage_Resolution->clear(); //拍照使用的分辨率 26 | foreach(QSize size, device->photoResolutions()) 27 | { 28 | QString str=QString::asprintf("%d X %d",size.width(),size.height()); 29 | ui->comboCam_PhotoRes->addItem(str); //支持的拍照分辨率 30 | ui->comboImage_Resolution->addItem(str,size); //拍照使用的分辨率,添加QSize用户数据 31 | } 32 | 33 | ui->comboCam_VideoRes->clear(); //支持的视频分辨率 34 | ui->comboCam_FrameRate->clear(); //支持的帧率范围 35 | ui->comboVideo_Resolution->clear(); //录像用的分辨率 36 | foreach(QCameraFormat format, device->videoFormats()) 37 | { 38 | QSize size=format.resolution(); 39 | QString str=QString::asprintf("%d X %d",size.width(),size.height()); 40 | ui->comboCam_VideoRes->addItem(str); 41 | ui->comboVideo_Resolution->addItem(str,size); //添加QSize用户数据 42 | 43 | str=QString::asprintf("%.1f ~ %.1f",format.minFrameRate(),format.maxFrameRate()); 44 | ui->comboCam_FrameRate->addItem(str); 45 | } 46 | } 47 | 48 | void MainWindow::showCameraSupportFeatures(QCamera *aCamera) 49 | {//显示摄像头支持的特性 50 | QCamera::Features features= aCamera->supportedFeatures(); 51 | 52 | bool supported=features.testFlag(QCamera::Feature::ColorTemperature); 53 | ui->chkBoxCam_Color->setChecked(supported); 54 | 55 | supported=features.testFlag(QCamera::Feature::ExposureCompensation); 56 | ui->chkBoxCam_Exposure->setChecked(supported); 57 | 58 | supported=features.testFlag(QCamera::Feature::IsoSensitivity); 59 | ui->chkBoxCam_Iso->setChecked(supported); 60 | 61 | supported=features.testFlag(QCamera::Feature::CustomFocusPoint); 62 | ui->chkBoxCam_Custom->setChecked(supported); 63 | 64 | supported=features.testFlag(QCamera::Feature::ManualExposureTime); 65 | ui->chkBoxCam_Manual->setChecked(supported); 66 | 67 | supported=features.testFlag(QCamera::Feature::FocusDistance); 68 | ui->chkBoxCam_Focus->setChecked(supported); 69 | } 70 | 71 | void MainWindow::closeEvent(QCloseEvent *event) 72 | { 73 | if (m_isWorking) 74 | { 75 | if(recorder->recorderState() == QMediaRecorder::RecordingState) //正在录制视频 76 | recorder->stop(); //停止录制视频 77 | camera->stop(); //关闭摄像头 78 | } 79 | event->accept(); 80 | } 81 | 82 | MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), 83 | ui(new Ui::MainWindow) 84 | { 85 | ui->setupUi(this); 86 | 87 | labDuration=new QLabel("录制时间: "); 88 | labDuration->setMinimumWidth(120); 89 | ui->statusBar->addWidget(labDuration); 90 | 91 | labFormatInfo=new QLabel("图片分辨率: "); 92 | labFormatInfo->setMinimumWidth(150); 93 | ui->statusBar->addWidget(labFormatInfo); 94 | 95 | labInfo=new QLabel("信息"); 96 | ui->statusBar->addPermanentWidget(labInfo); 97 | 98 | //1. 发现摄像头 99 | QCameraDevice defaultCameraDevice= QMediaDevices::defaultVideoInput(); 100 | if (defaultCameraDevice.isNull()) 101 | { 102 | QMessageBox::critical(this,"提示","没有发现摄像头"); 103 | return; 104 | } 105 | QByteArray defaultCameraID=defaultCameraDevice.id(); 106 | ui->actStartCamera->setEnabled(true); 107 | 108 | // disconnect(ui->comboCam_List); //解除与comboCam_List连接的所有槽函数 109 | int index=0; 110 | for(int i=0; icomboCam_List->addItem(device.description()+"(默认)",QVariant::fromValue(device)); 116 | index=i; 117 | } 118 | else 119 | ui->comboCam_List->addItem(device.description(),QVariant::fromValue(device)); 120 | } 121 | 122 | if (ui->comboCam_List->currentIndex() != index) 123 | ui->comboCam_List->setCurrentIndex(index); 124 | 125 | // foreach(QCameraDevice device, QMediaDevices::videoInputs()) 126 | // { 127 | // if (device.isDefault()) //是默认设备 128 | // ui->comboCam_List->addItem(device.description()+"(默认)",QVariant::fromValue(device)); 129 | // else 130 | // ui->comboCam_List->addItem(device.description(),QVariant::fromValue(device)); 131 | // } 132 | 133 | // ui->comboCam_List->addItem(cameraDevice.description()); 134 | // showCameraDeviceInfo(&cameraDevice); 135 | 136 | // ui->comboCam_List->addItem(cameraDevice.description()); 137 | 138 | //2. 创建抓取管理器session和各个设备 139 | session = new QMediaCaptureSession(this); //抓取管理器 140 | session->setVideoOutput(ui->videoPreview); //设置视频输出组件,用于视频预览 141 | //2.1 创建QAudioInput对象,用用音频输入 142 | QAudioInput *audioInput=new QAudioInput(this); 143 | audioInput->setDevice(QMediaDevices::defaultAudioInput()); 144 | session->setAudioInput(audioInput); //设置音频输入设备 145 | 146 | //2.2 创建QCamera对象,用于控制摄像头 147 | camera = new QCamera(this); //摄像头 148 | camera->setCameraDevice(defaultCameraDevice); // 149 | session->setCamera(camera); //为session设置摄像头 150 | connect(camera, &QCamera::activeChanged,this, &MainWindow::do_camera_activeChanged); 151 | connect(ui->comboCam_List,&QComboBox::currentIndexChanged, 152 | this, &MainWindow::do_camera_changed); 153 | do_camera_changed(ui->comboCam_List->currentIndex()); 154 | 155 | //2.3 创建QImageCapture对象,用于拍照 156 | imageCapture = new QImageCapture(this); //抓图器 157 | imageCapture->setQuality(QImageCapture::VeryHighQuality); 158 | session->setImageCapture(imageCapture); //为session设置抓图器 159 | connect(imageCapture,&QImageCapture::readyForCaptureChanged, 160 | this, &MainWindow::do_image_readyForCapture); 161 | connect(imageCapture,&QImageCapture::imageCaptured, 162 | this,&MainWindow::do_image_captured); 163 | connect(imageCapture, &QImageCapture::imageSaved, 164 | this, &MainWindow::do_image_saved); 165 | 166 | soundEffect =new QSoundEffect(this); //用于播放音效,拍照时的快门声音 167 | QString filename=":/sound/images/shutter.wav"; 168 | soundEffect->setSource(QUrl::fromLocalFile(filename)); 169 | 170 | //2.4 创建QMediaRecorder对象,用于录制视频 171 | recorder = new QMediaRecorder(this); //创建recorder 172 | session->setRecorder(recorder); //为session设置recorder 173 | connect(recorder, &QMediaRecorder::durationChanged, 174 | this, &MainWindow::do_recorder_duration); 175 | connect(recorder, &QMediaRecorder::recorderStateChanged, 176 | this, &MainWindow::do_recorder_stateChanged); 177 | connect(recorder, &QMediaRecorder::errorOccurred, 178 | this, &MainWindow::do_recorder_error); 179 | 180 | //3. 视频编码和文件格式,添加到录像设置的下拉列表框里,用于选择 181 | QMediaFormat format; 182 | //系统支持的视频编码格式 183 | foreach(QMediaFormat::VideoCodec codec, format.supportedVideoCodecs(QMediaFormat::Encode)) 184 | ui->comboVideo_Codec->addItem(QMediaFormat::videoCodecDescription(codec), 185 | QVariant::fromValue(codec)); 186 | //系统支持的文件格式 187 | foreach(QMediaFormat::FileFormat fileFormat, format.supportedFileFormats(QMediaFormat::Encode)) 188 | ui->comboVideo_FileFormat->addItem(QMediaFormat::fileFormatDescription(fileFormat), 189 | QVariant::fromValue(fileFormat)); 190 | } 191 | 192 | MainWindow::~MainWindow() 193 | { 194 | delete ui; 195 | } 196 | 197 | void MainWindow::do_camera_activeChanged(bool active) 198 | {//摄像头状态变化 199 | ui->actStartCamera->setEnabled(!active); 200 | ui->actStopCamera->setEnabled(active); 201 | 202 | ui->actVideoRecord->setEnabled(active); 203 | ui->comboCam_List->setEnabled(!active); 204 | 205 | m_isWorking = active; 206 | } 207 | 208 | void MainWindow::do_image_readyForCapture(bool ready) 209 | {//与 readyForCaptureChanged()信号关联 210 | ui->actCapture->setEnabled(ready); 211 | } 212 | 213 | void MainWindow::do_image_captured(int id, const QImage &preview) 214 | {//与 imageCaptured()信号关联 215 | Q_UNUSED(id); 216 | 217 | // QSize size=imageCapture->resolution(); //被设置了,但是不起作用, Qt 6.2.2的 bug 218 | // QString str=QString::asprintf("实际图片分辨率= %d X %d",size.width(),size.height()); 219 | QString str=QString::asprintf("实际图片分辨率= %d X %d",preview.width(),preview.height()); 220 | labFormatInfo->setText(str); 221 | 222 | QImage scaledImage = preview.scaledToWidth(ui->scrollArea->width()-30); 223 | ui->labImage->setPixmap(QPixmap::fromImage(scaledImage)); 224 | 225 | if(! ui->chkBox_SaveToFile->isChecked()) 226 | labInfo->setText("图片未保存为文件"); 227 | } 228 | 229 | void MainWindow::do_image_saved(int id, const QString &fileName) 230 | {//与 imageSaved()信号关联 231 | Q_UNUSED(id); 232 | labInfo->setText("图片保存为文件: "+fileName); 233 | } 234 | 235 | void MainWindow::do_recorder_duration(qint64 duration) 236 | {//与 durationChanged()信号关联 237 | labDuration->setText(QString::asprintf("录制时间:%.1f 秒 ",duration/1000.0)); 238 | } 239 | 240 | void MainWindow::do_recorder_stateChanged(QMediaRecorder::RecorderState state) 241 | {//与 recorderStateChanged()信号关联 242 | ui->actVideoRecord->setEnabled(state == QMediaRecorder::StoppedState); 243 | ui->actVideoStop->setEnabled(state == QMediaRecorder::RecordingState); 244 | } 245 | 246 | void MainWindow::do_recorder_error(QMediaRecorder::Error error, const QString &errorString) 247 | {//与 errorOccurred()信号关联 248 | Q_UNUSED(error); 249 | labInfo->setText(errorString); 250 | } 251 | 252 | void MainWindow::on_actStartCamera_triggered() 253 | {//开启摄像头 254 | camera->start(); 255 | } 256 | 257 | void MainWindow::on_actStopCamera_triggered() 258 | {//关闭摄像头 259 | if (recorder->recorderState() == QMediaRecorder::RecordingState) 260 | recorder->stop(); //停止录像 261 | camera->stop(); 262 | } 263 | 264 | void MainWindow::on_actCapture_triggered() 265 | {//"拍照" 按钮 266 | int index=ui->comboImage_Quality->currentIndex(); 267 | imageCapture->setQuality(QImageCapture::Quality(index)); //图片文件编码品质 268 | 269 | index=ui->comboImage_Resolution->currentIndex(); 270 | QVariant var=ui->comboImage_Resolution->itemData(index); //用户数据 271 | imageCapture->setResolution(var.toSize()); //设置分辨率 272 | 273 | // imageCapture->setResolution(640, 480); //直接设置也不起作用,是Qt 6.2.2中的bug 274 | if (ui->chkBox_SaveToFile->isChecked()) 275 | imageCapture->captureToFile(); //拍照并保存到文件 276 | else 277 | imageCapture->capture(); //拍照 278 | if (ui->chkBox_Sound->isChecked()) 279 | soundEffect->play(); //播放快门音效 280 | ui->tabWidget->setCurrentIndex(0); 281 | } 282 | 283 | void MainWindow::on_actVideoRecord_triggered() 284 | {//"开始录像"按钮 285 | QString selectedFile=ui->editVideo_OutputFile->text().trimmed(); 286 | if (selectedFile.isEmpty()) 287 | { 288 | QMessageBox::critical(this,"错误","请先设置录像输出文件"); 289 | return; 290 | } 291 | 292 | if (QFile::exists(selectedFile)) 293 | if (!QFile::remove(selectedFile)) 294 | { 295 | QMessageBox::critical(this,"错误","所设置录像输出文件被占用,无法删除"); 296 | return; 297 | } 298 | 299 | recorder->setEncodingMode(QMediaRecorder::ConstantQualityEncoding); //按固定品质编码 300 | int index =ui->comboViedo_Quality->currentIndex(); 301 | recorder->setQuality(QMediaRecorder::Quality(index)); //编码品质 302 | 303 | //设置媒介格式 304 | QMediaFormat mediaFormat; 305 | index=ui->comboVideo_Codec->currentIndex(); 306 | QVariant var= ui->comboVideo_Codec->itemData(index); //获取用户数据 307 | QMediaFormat::VideoCodec codec=var.value(); 308 | mediaFormat.setVideoCodec(codec); //设置视频编码 309 | 310 | index=ui->comboVideo_FileFormat->currentIndex(); 311 | var=ui->comboVideo_FileFormat->itemData(index); 312 | QMediaFormat::FileFormat fileFormat=var.value(); 313 | mediaFormat.setFileFormat(fileFormat); //设置文件格式 314 | 315 | recorder->setMediaFormat(mediaFormat); //设置媒介格式 316 | 317 | index=ui->comboVideo_Resolution->currentIndex(); 318 | var=ui->comboVideo_Resolution->itemData(index); //获取用户数据 319 | recorder->setVideoResolution(var.toSize()); //设置视频分辨率 320 | 321 | labInfo->clear(); 322 | recorder->setOutputLocation(QUrl::fromLocalFile(selectedFile)); //设置输出文件 323 | recorder->record(); 324 | } 325 | 326 | void MainWindow::on_actVideoStop_triggered() 327 | {//停止录像 328 | recorder->stop(); 329 | } 330 | 331 | void MainWindow::on_btnVideoFile_clicked() 332 | { 333 | QString curPath=QDir::homePath(); 334 | QString dlgTitle="选择保存文件"; 335 | QString filter="MP4视频文件(*.mp4);;WMV视频文件(*.wmv);;所有文件(*.*)"; 336 | QString selectedFile=QFileDialog::getSaveFileName(this,dlgTitle,curPath,filter); 337 | if (!selectedFile.isEmpty()) 338 | ui->editVideo_OutputFile->setText(selectedFile); 339 | } 340 | 341 | void MainWindow::do_camera_changed(int index) 342 | { 343 | QVariant var=ui->comboCam_List->itemData(index); 344 | QCameraDevice device = var.value(); 345 | showCameraDeviceInfo(&device); //显示摄像头设备信息 346 | 347 | camera->setCameraDevice(device); //重新设置摄像头设备 348 | showCameraSupportFeatures(camera); //显示摄像头支持的特性 349 | } 350 | 351 | -------------------------------------------------------------------------------- /qt_source/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | QT_BEGIN_NAMESPACE 11 | namespace Ui { class MainWindow; } 12 | QT_END_NAMESPACE 13 | 14 | 15 | class MainWindow : public QMainWindow 16 | { 17 | Q_OBJECT 18 | 19 | private: 20 | QMediaCaptureSession *session; //抓取管理器 21 | QCamera *camera; //摄像头 22 | 23 | QImageCapture *imageCapture; //抓图器 24 | QSoundEffect *soundEffect; //用于拍照时播放快门音效 25 | 26 | QMediaRecorder *recorder; //录像 27 | 28 | QLabel *labDuration; //用于状态栏显示信息 29 | QLabel *labInfo; 30 | QLabel *labFormatInfo; 31 | bool m_isWorking=false; //是否已开启摄像头 32 | 33 | void iniCamera();//初始化 34 | void iniImageCapture();//初始化静态画图 35 | void iniVideoRecorder();//初始化视频录制 36 | 37 | void showCameraDeviceInfo(QCameraDevice *device); 38 | void showCameraSupportFeatures(QCamera *aCamera); 39 | void closeEvent(QCloseEvent *event); 40 | public: 41 | MainWindow(QWidget *parent = nullptr); 42 | ~MainWindow(); 43 | 44 | private slots: 45 | void do_camera_changed(int index); //与摄像头下拉列表框的信号关联 46 | 47 | //与QCamera的信号关联 48 | void do_camera_activeChanged(bool active); 49 | 50 | //与QImageCapture的信号关联 51 | void do_image_readyForCapture(bool ready); 52 | void do_image_captured(int id, const QImage &preview); 53 | void do_image_saved(int id, const QString &fileName); 54 | 55 | //与QMediaRecorder的信号关联 56 | void do_recorder_duration(qint64 duration); 57 | void do_recorder_stateChanged(QMediaRecorder::RecorderState state); 58 | void do_recorder_error(QMediaRecorder::Error error, const QString &errorString); 59 | 60 | 61 | void on_actStartCamera_triggered(); 62 | 63 | void on_actStopCamera_triggered(); 64 | 65 | void on_actCapture_triggered(); 66 | 67 | void on_actVideoRecord_triggered(); 68 | 69 | void on_actVideoStop_triggered(); 70 | 71 | void on_btnVideoFile_clicked(); 72 | 73 | 74 | private: 75 | Ui::MainWindow *ui; 76 | }; 77 | 78 | #endif // MAINWINDOW_H 79 | -------------------------------------------------------------------------------- /qt_source/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 913 10 | 538 11 | 12 | 13 | 14 | 15 | 10 16 | 17 | 18 | 19 | 摄像头拍照与录像 20 | 21 | 22 | 23 | 24 | 2 25 | 26 | 27 | 2 28 | 29 | 30 | 2 31 | 32 | 33 | 2 34 | 35 | 36 | 37 | 38 | QFrame::Panel 39 | 40 | 41 | QFrame::Raised 42 | 43 | 44 | 45 | 5 46 | 47 | 48 | 5 49 | 50 | 51 | 5 52 | 53 | 54 | 5 55 | 56 | 57 | 58 | 59 | 摄像头设备 60 | 61 | 62 | 63 | 64 | 65 | 66 | 80 67 | 16777215 68 | 69 | 70 | 71 | 摄像头 72 | 73 | 74 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 支持的拍照分辨率 85 | 86 | 87 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 摄像头位置 98 | 99 | 100 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 未设置 109 | 110 | 111 | 112 | 113 | 后置 114 | 115 | 116 | 117 | 118 | 前置 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 支持的视频分辨率 127 | 128 | 129 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 视频帧率范围 140 | 141 | 142 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 摄像头控制特性 156 | 157 | 158 | 159 | 160 | 161 | ColorTemperature 162 | 163 | 164 | 165 | 166 | 167 | 168 | ManualExposureTime 169 | 170 | 171 | 172 | 173 | 174 | 175 | ExposureCompensation 176 | 177 | 178 | 179 | 180 | 181 | 182 | CustomFocusPoint 183 | 184 | 185 | 186 | 187 | 188 | 189 | IsoSensitivity 190 | 191 | 192 | 193 | 194 | 195 | 196 | FocusDistance 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | Qt::Horizontal 210 | 211 | 212 | 213 | 摄像头预览 214 | 215 | 216 | 217 | 218 | 219 | 220 | 150 221 | 0 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 1 231 | 232 | 233 | true 234 | 235 | 236 | 237 | 拍摄的照片 238 | 239 | 240 | 241 | 0 242 | 243 | 244 | 245 | 246 | 拍照设置 247 | 248 | 249 | 250 | 5 251 | 252 | 253 | 5 254 | 255 | 256 | 257 | 258 | 图片编码品质 259 | 260 | 261 | 262 | 263 | 264 | 265 | 3 266 | 267 | 268 | 269 | VeryLowQuality 270 | 271 | 272 | 273 | 274 | LowQuality 275 | 276 | 277 | 278 | 279 | NormalQuality 280 | 281 | 282 | 283 | 284 | HighQuality 285 | 286 | 287 | 288 | 289 | VeryHighQuality 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 播放音效 298 | 299 | 300 | true 301 | 302 | 303 | 304 | 305 | 306 | 307 | 图片分辨率 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 保存为文件 318 | 319 | 320 | true 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | true 331 | 332 | 333 | 334 | 335 | 0 336 | 0 337 | 621 338 | 146 339 | 340 | 341 | 342 | 343 | 344 | 345 | 拍照的图片 346 | 347 | 348 | Qt::AlignCenter 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 录像设置 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 保存文件 369 | 370 | 371 | 372 | :/images/images/104.bmp:/images/images/104.bmp 373 | 374 | 375 | false 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 录像设置 392 | 393 | 394 | 395 | 9 396 | 397 | 398 | 399 | 400 | 视频编码 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 文件格式 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 视频编码品质 421 | 422 | 423 | 424 | 425 | 426 | 427 | 3 428 | 429 | 430 | 431 | VeryLowQuality 432 | 433 | 434 | 435 | 436 | LowQuality 437 | 438 | 439 | 440 | 441 | NormalQuality 442 | 443 | 444 | 445 | 446 | HighQuality 447 | 448 | 449 | 450 | 451 | VeryHighQuality 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 视频分辨率 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | Qt::Vertical 473 | 474 | 475 | 476 | 20 477 | 101 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | Qt::ToolButtonTextUnderIcon 492 | 493 | 494 | TopToolBarArea 495 | 496 | 497 | false 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | false 513 | 514 | 515 | 516 | :/images/images/video_chat.ico:/images/images/video_chat.ico 517 | 518 | 519 | 开启摄像头 520 | 521 | 522 | 开启摄像头 523 | 524 | 525 | 526 | 527 | false 528 | 529 | 530 | 531 | :/images/images/remove_user.ico:/images/images/remove_user.ico 532 | 533 | 534 | 关闭摄像头 535 | 536 | 537 | 关闭摄像头 538 | 539 | 540 | 541 | 542 | false 543 | 544 | 545 | 546 | :/images/images/5.ico:/images/images/5.ico 547 | 548 | 549 | 开始录像 550 | 551 | 552 | 开始录像 553 | 554 | 555 | F8 556 | 557 | 558 | 559 | 560 | false 561 | 562 | 563 | 564 | :/images/images/file_pictures.ico:/images/images/file_pictures.ico 565 | 566 | 567 | 拍照 568 | 569 | 570 | 拍照 571 | 572 | 573 | F10 574 | 575 | 576 | 577 | 578 | 579 | :/images/images/exit_24.ico:/images/images/exit_24.ico 580 | 581 | 582 | 退出 583 | 584 | 585 | 退出 586 | 587 | 588 | 589 | 590 | false 591 | 592 | 593 | 594 | :/images/images/Shut Down.ico:/images/images/Shut Down.ico 595 | 596 | 597 | 停止录像 598 | 599 | 600 | 停止录像 601 | 602 | 603 | 604 | 605 | 606 | 607 | QVideoWidget 608 | QWidget 609 |
<QVideoWidget>
610 | 1 611 |
612 |
613 | 614 | 615 | 616 | 617 | 618 | actQuit 619 | triggered() 620 | MainWindow 621 | close() 622 | 623 | 624 | -1 625 | -1 626 | 627 | 628 | 288 629 | 178 630 | 631 | 632 | 633 | 634 |
635 | -------------------------------------------------------------------------------- /qt_source/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/volumn.bmp 4 | images/mute.bmp 5 | images/104.bmp 6 | images/22.ico 7 | images/5.ico 8 | images/23.ico 9 | images/video_chat.ico 10 | images/remove_user.ico 11 | images/Shut Down.ico 12 | images/exit_24.ico 13 | images/file_pictures.ico 14 | images/824.bmp 15 | images/08.JPG 16 | 17 | 18 | images/shutter.wav 19 | 20 | 21 | -------------------------------------------------------------------------------- /qt_source/ui_mainwindow.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | ** Form generated from reading UI file 'mainwindow.ui' 3 | ** 4 | ** Created by: Qt User Interface Compiler version 6.2.4 5 | ** 6 | ** WARNING! All changes made in this file will be lost when recompiling UI file! 7 | ********************************************************************************/ 8 | 9 | #ifndef UI_MAINWINDOW_H 10 | #define UI_MAINWINDOW_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | QT_BEGIN_NAMESPACE 38 | 39 | class Ui_MainWindow 40 | { 41 | public: 42 | QAction *actStartCamera; 43 | QAction *actStopCamera; 44 | QAction *actVideoRecord; 45 | QAction *actCapture; 46 | QAction *actQuit; 47 | QAction *actVideoStop; 48 | QWidget *centralWidget; 49 | QVBoxLayout *verticalLayout_3; 50 | QFrame *frame; 51 | QHBoxLayout *horizontalLayout; 52 | QGroupBox *groupBox_Camera; 53 | QGridLayout *gridLayout_3; 54 | QLabel *label; 55 | QComboBox *comboCam_List; 56 | QLabel *label_3; 57 | QComboBox *comboCam_PhotoRes; 58 | QLabel *label_2; 59 | QComboBox *comboCam_Position; 60 | QLabel *label_4; 61 | QComboBox *comboCam_VideoRes; 62 | QLabel *label_5; 63 | QComboBox *comboCam_FrameRate; 64 | QGroupBox *groupBox_2; 65 | QGridLayout *gridLayout; 66 | QCheckBox *chkBoxCam_Color; 67 | QCheckBox *chkBoxCam_Manual; 68 | QCheckBox *chkBoxCam_Exposure; 69 | QCheckBox *chkBoxCam_Custom; 70 | QCheckBox *chkBoxCam_Iso; 71 | QCheckBox *chkBoxCam_Focus; 72 | QSplitter *splitter; 73 | QGroupBox *groupBox; 74 | QVBoxLayout *verticalLayout; 75 | QVideoWidget *videoPreview; 76 | QTabWidget *tabWidget; 77 | QWidget *tab; 78 | QVBoxLayout *verticalLayout_2; 79 | QGroupBox *groupBox_3; 80 | QGridLayout *gridLayout_2; 81 | QLabel *label_6; 82 | QComboBox *comboImage_Quality; 83 | QCheckBox *chkBox_Sound; 84 | QLabel *label_11; 85 | QComboBox *comboImage_Resolution; 86 | QCheckBox *chkBox_SaveToFile; 87 | QScrollArea *scrollArea; 88 | QWidget *scrollAreaWidgetContents; 89 | QVBoxLayout *verticalLayout_5; 90 | QLabel *labImage; 91 | QWidget *tab_2; 92 | QVBoxLayout *verticalLayout_4; 93 | QHBoxLayout *horizontalLayout_3; 94 | QPushButton *btnVideoFile; 95 | QLineEdit *editVideo_OutputFile; 96 | QGroupBox *groupBox_5; 97 | QFormLayout *formLayout; 98 | QLabel *label_8; 99 | QComboBox *comboVideo_Codec; 100 | QLabel *label_9; 101 | QComboBox *comboVideo_FileFormat; 102 | QLabel *label_10; 103 | QComboBox *comboViedo_Quality; 104 | QLabel *label_7; 105 | QComboBox *comboVideo_Resolution; 106 | QSpacerItem *verticalSpacer; 107 | QToolBar *mainToolBar; 108 | QStatusBar *statusBar; 109 | 110 | void setupUi(QMainWindow *MainWindow) 111 | { 112 | if (MainWindow->objectName().isEmpty()) 113 | MainWindow->setObjectName(QString::fromUtf8("MainWindow")); 114 | MainWindow->resize(913, 538); 115 | QFont font; 116 | font.setPointSize(10); 117 | MainWindow->setFont(font); 118 | actStartCamera = new QAction(MainWindow); 119 | actStartCamera->setObjectName(QString::fromUtf8("actStartCamera")); 120 | actStartCamera->setEnabled(false); 121 | QIcon icon; 122 | icon.addFile(QString::fromUtf8(":/images/images/video_chat.ico"), QSize(), QIcon::Normal, QIcon::Off); 123 | actStartCamera->setIcon(icon); 124 | actStopCamera = new QAction(MainWindow); 125 | actStopCamera->setObjectName(QString::fromUtf8("actStopCamera")); 126 | actStopCamera->setEnabled(false); 127 | QIcon icon1; 128 | icon1.addFile(QString::fromUtf8(":/images/images/remove_user.ico"), QSize(), QIcon::Normal, QIcon::Off); 129 | actStopCamera->setIcon(icon1); 130 | actVideoRecord = new QAction(MainWindow); 131 | actVideoRecord->setObjectName(QString::fromUtf8("actVideoRecord")); 132 | actVideoRecord->setEnabled(false); 133 | QIcon icon2; 134 | icon2.addFile(QString::fromUtf8(":/images/images/5.ico"), QSize(), QIcon::Normal, QIcon::Off); 135 | actVideoRecord->setIcon(icon2); 136 | actCapture = new QAction(MainWindow); 137 | actCapture->setObjectName(QString::fromUtf8("actCapture")); 138 | actCapture->setEnabled(false); 139 | QIcon icon3; 140 | icon3.addFile(QString::fromUtf8(":/images/images/file_pictures.ico"), QSize(), QIcon::Normal, QIcon::Off); 141 | actCapture->setIcon(icon3); 142 | actQuit = new QAction(MainWindow); 143 | actQuit->setObjectName(QString::fromUtf8("actQuit")); 144 | QIcon icon4; 145 | icon4.addFile(QString::fromUtf8(":/images/images/exit_24.ico"), QSize(), QIcon::Normal, QIcon::Off); 146 | actQuit->setIcon(icon4); 147 | actVideoStop = new QAction(MainWindow); 148 | actVideoStop->setObjectName(QString::fromUtf8("actVideoStop")); 149 | actVideoStop->setEnabled(false); 150 | QIcon icon5; 151 | icon5.addFile(QString::fromUtf8(":/images/images/Shut Down.ico"), QSize(), QIcon::Normal, QIcon::Off); 152 | actVideoStop->setIcon(icon5); 153 | centralWidget = new QWidget(MainWindow); 154 | centralWidget->setObjectName(QString::fromUtf8("centralWidget")); 155 | verticalLayout_3 = new QVBoxLayout(centralWidget); 156 | verticalLayout_3->setSpacing(6); 157 | verticalLayout_3->setContentsMargins(11, 11, 11, 11); 158 | verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); 159 | verticalLayout_3->setContentsMargins(2, 2, 2, 2); 160 | frame = new QFrame(centralWidget); 161 | frame->setObjectName(QString::fromUtf8("frame")); 162 | frame->setFrameShape(QFrame::Panel); 163 | frame->setFrameShadow(QFrame::Raised); 164 | horizontalLayout = new QHBoxLayout(frame); 165 | horizontalLayout->setSpacing(6); 166 | horizontalLayout->setContentsMargins(11, 11, 11, 11); 167 | horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); 168 | horizontalLayout->setContentsMargins(5, 5, 5, 5); 169 | groupBox_Camera = new QGroupBox(frame); 170 | groupBox_Camera->setObjectName(QString::fromUtf8("groupBox_Camera")); 171 | gridLayout_3 = new QGridLayout(groupBox_Camera); 172 | gridLayout_3->setSpacing(6); 173 | gridLayout_3->setContentsMargins(11, 11, 11, 11); 174 | gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3")); 175 | label = new QLabel(groupBox_Camera); 176 | label->setObjectName(QString::fromUtf8("label")); 177 | label->setMaximumSize(QSize(80, 16777215)); 178 | label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); 179 | 180 | gridLayout_3->addWidget(label, 0, 0, 1, 1); 181 | 182 | comboCam_List = new QComboBox(groupBox_Camera); 183 | comboCam_List->setObjectName(QString::fromUtf8("comboCam_List")); 184 | 185 | gridLayout_3->addWidget(comboCam_List, 0, 1, 1, 1); 186 | 187 | label_3 = new QLabel(groupBox_Camera); 188 | label_3->setObjectName(QString::fromUtf8("label_3")); 189 | label_3->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); 190 | 191 | gridLayout_3->addWidget(label_3, 0, 2, 1, 1); 192 | 193 | comboCam_PhotoRes = new QComboBox(groupBox_Camera); 194 | comboCam_PhotoRes->setObjectName(QString::fromUtf8("comboCam_PhotoRes")); 195 | 196 | gridLayout_3->addWidget(comboCam_PhotoRes, 0, 3, 1, 1); 197 | 198 | label_2 = new QLabel(groupBox_Camera); 199 | label_2->setObjectName(QString::fromUtf8("label_2")); 200 | label_2->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); 201 | 202 | gridLayout_3->addWidget(label_2, 1, 0, 1, 1); 203 | 204 | comboCam_Position = new QComboBox(groupBox_Camera); 205 | comboCam_Position->addItem(QString()); 206 | comboCam_Position->addItem(QString()); 207 | comboCam_Position->addItem(QString()); 208 | comboCam_Position->setObjectName(QString::fromUtf8("comboCam_Position")); 209 | 210 | gridLayout_3->addWidget(comboCam_Position, 1, 1, 1, 1); 211 | 212 | label_4 = new QLabel(groupBox_Camera); 213 | label_4->setObjectName(QString::fromUtf8("label_4")); 214 | label_4->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); 215 | 216 | gridLayout_3->addWidget(label_4, 1, 2, 1, 1); 217 | 218 | comboCam_VideoRes = new QComboBox(groupBox_Camera); 219 | comboCam_VideoRes->setObjectName(QString::fromUtf8("comboCam_VideoRes")); 220 | 221 | gridLayout_3->addWidget(comboCam_VideoRes, 1, 3, 1, 1); 222 | 223 | label_5 = new QLabel(groupBox_Camera); 224 | label_5->setObjectName(QString::fromUtf8("label_5")); 225 | label_5->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); 226 | 227 | gridLayout_3->addWidget(label_5, 2, 2, 1, 1); 228 | 229 | comboCam_FrameRate = new QComboBox(groupBox_Camera); 230 | comboCam_FrameRate->setObjectName(QString::fromUtf8("comboCam_FrameRate")); 231 | 232 | gridLayout_3->addWidget(comboCam_FrameRate, 2, 3, 1, 1); 233 | 234 | 235 | horizontalLayout->addWidget(groupBox_Camera); 236 | 237 | groupBox_2 = new QGroupBox(frame); 238 | groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); 239 | gridLayout = new QGridLayout(groupBox_2); 240 | gridLayout->setSpacing(6); 241 | gridLayout->setContentsMargins(11, 11, 11, 11); 242 | gridLayout->setObjectName(QString::fromUtf8("gridLayout")); 243 | chkBoxCam_Color = new QCheckBox(groupBox_2); 244 | chkBoxCam_Color->setObjectName(QString::fromUtf8("chkBoxCam_Color")); 245 | 246 | gridLayout->addWidget(chkBoxCam_Color, 0, 0, 1, 1); 247 | 248 | chkBoxCam_Manual = new QCheckBox(groupBox_2); 249 | chkBoxCam_Manual->setObjectName(QString::fromUtf8("chkBoxCam_Manual")); 250 | 251 | gridLayout->addWidget(chkBoxCam_Manual, 0, 1, 1, 1); 252 | 253 | chkBoxCam_Exposure = new QCheckBox(groupBox_2); 254 | chkBoxCam_Exposure->setObjectName(QString::fromUtf8("chkBoxCam_Exposure")); 255 | 256 | gridLayout->addWidget(chkBoxCam_Exposure, 1, 0, 1, 1); 257 | 258 | chkBoxCam_Custom = new QCheckBox(groupBox_2); 259 | chkBoxCam_Custom->setObjectName(QString::fromUtf8("chkBoxCam_Custom")); 260 | 261 | gridLayout->addWidget(chkBoxCam_Custom, 1, 1, 1, 1); 262 | 263 | chkBoxCam_Iso = new QCheckBox(groupBox_2); 264 | chkBoxCam_Iso->setObjectName(QString::fromUtf8("chkBoxCam_Iso")); 265 | 266 | gridLayout->addWidget(chkBoxCam_Iso, 2, 0, 1, 1); 267 | 268 | chkBoxCam_Focus = new QCheckBox(groupBox_2); 269 | chkBoxCam_Focus->setObjectName(QString::fromUtf8("chkBoxCam_Focus")); 270 | 271 | gridLayout->addWidget(chkBoxCam_Focus, 2, 1, 1, 1); 272 | 273 | 274 | horizontalLayout->addWidget(groupBox_2); 275 | 276 | horizontalLayout->setStretch(0, 1); 277 | 278 | verticalLayout_3->addWidget(frame); 279 | 280 | splitter = new QSplitter(centralWidget); 281 | splitter->setObjectName(QString::fromUtf8("splitter")); 282 | splitter->setOrientation(Qt::Horizontal); 283 | groupBox = new QGroupBox(splitter); 284 | groupBox->setObjectName(QString::fromUtf8("groupBox")); 285 | verticalLayout = new QVBoxLayout(groupBox); 286 | verticalLayout->setSpacing(6); 287 | verticalLayout->setContentsMargins(11, 11, 11, 11); 288 | verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); 289 | videoPreview = new QVideoWidget(groupBox); 290 | videoPreview->setObjectName(QString::fromUtf8("videoPreview")); 291 | videoPreview->setMinimumSize(QSize(150, 0)); 292 | 293 | verticalLayout->addWidget(videoPreview); 294 | 295 | splitter->addWidget(groupBox); 296 | tabWidget = new QTabWidget(splitter); 297 | tabWidget->setObjectName(QString::fromUtf8("tabWidget")); 298 | tabWidget->setDocumentMode(true); 299 | tab = new QWidget(); 300 | tab->setObjectName(QString::fromUtf8("tab")); 301 | verticalLayout_2 = new QVBoxLayout(tab); 302 | verticalLayout_2->setSpacing(6); 303 | verticalLayout_2->setContentsMargins(11, 11, 11, 11); 304 | verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); 305 | verticalLayout_2->setContentsMargins(-1, -1, -1, 0); 306 | groupBox_3 = new QGroupBox(tab); 307 | groupBox_3->setObjectName(QString::fromUtf8("groupBox_3")); 308 | gridLayout_2 = new QGridLayout(groupBox_3); 309 | gridLayout_2->setSpacing(6); 310 | gridLayout_2->setContentsMargins(11, 11, 11, 11); 311 | gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2")); 312 | gridLayout_2->setContentsMargins(-1, 5, -1, 5); 313 | label_6 = new QLabel(groupBox_3); 314 | label_6->setObjectName(QString::fromUtf8("label_6")); 315 | 316 | gridLayout_2->addWidget(label_6, 0, 0, 1, 1); 317 | 318 | comboImage_Quality = new QComboBox(groupBox_3); 319 | comboImage_Quality->addItem(QString()); 320 | comboImage_Quality->addItem(QString()); 321 | comboImage_Quality->addItem(QString()); 322 | comboImage_Quality->addItem(QString()); 323 | comboImage_Quality->addItem(QString()); 324 | comboImage_Quality->setObjectName(QString::fromUtf8("comboImage_Quality")); 325 | 326 | gridLayout_2->addWidget(comboImage_Quality, 0, 1, 1, 1); 327 | 328 | chkBox_Sound = new QCheckBox(groupBox_3); 329 | chkBox_Sound->setObjectName(QString::fromUtf8("chkBox_Sound")); 330 | chkBox_Sound->setChecked(true); 331 | 332 | gridLayout_2->addWidget(chkBox_Sound, 0, 2, 1, 1); 333 | 334 | label_11 = new QLabel(groupBox_3); 335 | label_11->setObjectName(QString::fromUtf8("label_11")); 336 | 337 | gridLayout_2->addWidget(label_11, 1, 0, 1, 1); 338 | 339 | comboImage_Resolution = new QComboBox(groupBox_3); 340 | comboImage_Resolution->setObjectName(QString::fromUtf8("comboImage_Resolution")); 341 | 342 | gridLayout_2->addWidget(comboImage_Resolution, 1, 1, 1, 1); 343 | 344 | chkBox_SaveToFile = new QCheckBox(groupBox_3); 345 | chkBox_SaveToFile->setObjectName(QString::fromUtf8("chkBox_SaveToFile")); 346 | chkBox_SaveToFile->setChecked(true); 347 | 348 | gridLayout_2->addWidget(chkBox_SaveToFile, 1, 2, 1, 1); 349 | 350 | gridLayout_2->setColumnStretch(1, 1); 351 | 352 | verticalLayout_2->addWidget(groupBox_3); 353 | 354 | scrollArea = new QScrollArea(tab); 355 | scrollArea->setObjectName(QString::fromUtf8("scrollArea")); 356 | scrollArea->setWidgetResizable(true); 357 | scrollAreaWidgetContents = new QWidget(); 358 | scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents")); 359 | scrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 146)); 360 | verticalLayout_5 = new QVBoxLayout(scrollAreaWidgetContents); 361 | verticalLayout_5->setSpacing(6); 362 | verticalLayout_5->setContentsMargins(11, 11, 11, 11); 363 | verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5")); 364 | labImage = new QLabel(scrollAreaWidgetContents); 365 | labImage->setObjectName(QString::fromUtf8("labImage")); 366 | labImage->setAlignment(Qt::AlignCenter); 367 | 368 | verticalLayout_5->addWidget(labImage); 369 | 370 | scrollArea->setWidget(scrollAreaWidgetContents); 371 | 372 | verticalLayout_2->addWidget(scrollArea); 373 | 374 | tabWidget->addTab(tab, QString()); 375 | tab_2 = new QWidget(); 376 | tab_2->setObjectName(QString::fromUtf8("tab_2")); 377 | verticalLayout_4 = new QVBoxLayout(tab_2); 378 | verticalLayout_4->setSpacing(6); 379 | verticalLayout_4->setContentsMargins(11, 11, 11, 11); 380 | verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4")); 381 | horizontalLayout_3 = new QHBoxLayout(); 382 | horizontalLayout_3->setSpacing(6); 383 | horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); 384 | btnVideoFile = new QPushButton(tab_2); 385 | btnVideoFile->setObjectName(QString::fromUtf8("btnVideoFile")); 386 | QIcon icon6; 387 | icon6.addFile(QString::fromUtf8(":/images/images/104.bmp"), QSize(), QIcon::Normal, QIcon::Off); 388 | btnVideoFile->setIcon(icon6); 389 | btnVideoFile->setFlat(false); 390 | 391 | horizontalLayout_3->addWidget(btnVideoFile); 392 | 393 | editVideo_OutputFile = new QLineEdit(tab_2); 394 | editVideo_OutputFile->setObjectName(QString::fromUtf8("editVideo_OutputFile")); 395 | 396 | horizontalLayout_3->addWidget(editVideo_OutputFile); 397 | 398 | 399 | verticalLayout_4->addLayout(horizontalLayout_3); 400 | 401 | groupBox_5 = new QGroupBox(tab_2); 402 | groupBox_5->setObjectName(QString::fromUtf8("groupBox_5")); 403 | formLayout = new QFormLayout(groupBox_5); 404 | formLayout->setSpacing(6); 405 | formLayout->setContentsMargins(11, 11, 11, 11); 406 | formLayout->setObjectName(QString::fromUtf8("formLayout")); 407 | formLayout->setVerticalSpacing(9); 408 | label_8 = new QLabel(groupBox_5); 409 | label_8->setObjectName(QString::fromUtf8("label_8")); 410 | 411 | formLayout->setWidget(0, QFormLayout::LabelRole, label_8); 412 | 413 | comboVideo_Codec = new QComboBox(groupBox_5); 414 | comboVideo_Codec->setObjectName(QString::fromUtf8("comboVideo_Codec")); 415 | 416 | formLayout->setWidget(0, QFormLayout::FieldRole, comboVideo_Codec); 417 | 418 | label_9 = new QLabel(groupBox_5); 419 | label_9->setObjectName(QString::fromUtf8("label_9")); 420 | 421 | formLayout->setWidget(1, QFormLayout::LabelRole, label_9); 422 | 423 | comboVideo_FileFormat = new QComboBox(groupBox_5); 424 | comboVideo_FileFormat->setObjectName(QString::fromUtf8("comboVideo_FileFormat")); 425 | 426 | formLayout->setWidget(1, QFormLayout::FieldRole, comboVideo_FileFormat); 427 | 428 | label_10 = new QLabel(groupBox_5); 429 | label_10->setObjectName(QString::fromUtf8("label_10")); 430 | 431 | formLayout->setWidget(2, QFormLayout::LabelRole, label_10); 432 | 433 | comboViedo_Quality = new QComboBox(groupBox_5); 434 | comboViedo_Quality->addItem(QString()); 435 | comboViedo_Quality->addItem(QString()); 436 | comboViedo_Quality->addItem(QString()); 437 | comboViedo_Quality->addItem(QString()); 438 | comboViedo_Quality->addItem(QString()); 439 | comboViedo_Quality->setObjectName(QString::fromUtf8("comboViedo_Quality")); 440 | 441 | formLayout->setWidget(2, QFormLayout::FieldRole, comboViedo_Quality); 442 | 443 | label_7 = new QLabel(groupBox_5); 444 | label_7->setObjectName(QString::fromUtf8("label_7")); 445 | 446 | formLayout->setWidget(3, QFormLayout::LabelRole, label_7); 447 | 448 | comboVideo_Resolution = new QComboBox(groupBox_5); 449 | comboVideo_Resolution->setObjectName(QString::fromUtf8("comboVideo_Resolution")); 450 | 451 | formLayout->setWidget(3, QFormLayout::FieldRole, comboVideo_Resolution); 452 | 453 | 454 | verticalLayout_4->addWidget(groupBox_5); 455 | 456 | verticalSpacer = new QSpacerItem(20, 101, QSizePolicy::Minimum, QSizePolicy::Expanding); 457 | 458 | verticalLayout_4->addItem(verticalSpacer); 459 | 460 | tabWidget->addTab(tab_2, QString()); 461 | splitter->addWidget(tabWidget); 462 | 463 | verticalLayout_3->addWidget(splitter); 464 | 465 | verticalLayout_3->setStretch(1, 1); 466 | MainWindow->setCentralWidget(centralWidget); 467 | mainToolBar = new QToolBar(MainWindow); 468 | mainToolBar->setObjectName(QString::fromUtf8("mainToolBar")); 469 | mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 470 | MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar); 471 | statusBar = new QStatusBar(MainWindow); 472 | statusBar->setObjectName(QString::fromUtf8("statusBar")); 473 | MainWindow->setStatusBar(statusBar); 474 | 475 | mainToolBar->addAction(actStartCamera); 476 | mainToolBar->addAction(actStopCamera); 477 | mainToolBar->addSeparator(); 478 | mainToolBar->addAction(actCapture); 479 | mainToolBar->addSeparator(); 480 | mainToolBar->addAction(actVideoRecord); 481 | mainToolBar->addAction(actVideoStop); 482 | mainToolBar->addSeparator(); 483 | mainToolBar->addAction(actQuit); 484 | 485 | retranslateUi(MainWindow); 486 | QObject::connect(actQuit, &QAction::triggered, MainWindow, qOverload<>(&QMainWindow::close)); 487 | 488 | tabWidget->setCurrentIndex(1); 489 | comboImage_Quality->setCurrentIndex(3); 490 | comboViedo_Quality->setCurrentIndex(3); 491 | 492 | 493 | QMetaObject::connectSlotsByName(MainWindow); 494 | } // setupUi 495 | 496 | void retranslateUi(QMainWindow *MainWindow) 497 | { 498 | MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "\346\221\204\345\203\217\345\244\264\346\213\215\347\205\247\344\270\216\345\275\225\345\203\217", nullptr)); 499 | actStartCamera->setText(QCoreApplication::translate("MainWindow", "\345\274\200\345\220\257\346\221\204\345\203\217\345\244\264", nullptr)); 500 | #if QT_CONFIG(tooltip) 501 | actStartCamera->setToolTip(QCoreApplication::translate("MainWindow", "\345\274\200\345\220\257\346\221\204\345\203\217\345\244\264", nullptr)); 502 | #endif // QT_CONFIG(tooltip) 503 | actStopCamera->setText(QCoreApplication::translate("MainWindow", "\345\205\263\351\227\255\346\221\204\345\203\217\345\244\264", nullptr)); 504 | #if QT_CONFIG(tooltip) 505 | actStopCamera->setToolTip(QCoreApplication::translate("MainWindow", "\345\205\263\351\227\255\346\221\204\345\203\217\345\244\264", nullptr)); 506 | #endif // QT_CONFIG(tooltip) 507 | actVideoRecord->setText(QCoreApplication::translate("MainWindow", "\345\274\200\345\247\213\345\275\225\345\203\217", nullptr)); 508 | #if QT_CONFIG(tooltip) 509 | actVideoRecord->setToolTip(QCoreApplication::translate("MainWindow", "\345\274\200\345\247\213\345\275\225\345\203\217", nullptr)); 510 | #endif // QT_CONFIG(tooltip) 511 | #if QT_CONFIG(shortcut) 512 | actVideoRecord->setShortcut(QCoreApplication::translate("MainWindow", "F8", nullptr)); 513 | #endif // QT_CONFIG(shortcut) 514 | actCapture->setText(QCoreApplication::translate("MainWindow", "\346\213\215\347\205\247", nullptr)); 515 | #if QT_CONFIG(tooltip) 516 | actCapture->setToolTip(QCoreApplication::translate("MainWindow", "\346\213\215\347\205\247", nullptr)); 517 | #endif // QT_CONFIG(tooltip) 518 | #if QT_CONFIG(shortcut) 519 | actCapture->setShortcut(QCoreApplication::translate("MainWindow", "F10", nullptr)); 520 | #endif // QT_CONFIG(shortcut) 521 | actQuit->setText(QCoreApplication::translate("MainWindow", "\351\200\200\345\207\272", nullptr)); 522 | #if QT_CONFIG(tooltip) 523 | actQuit->setToolTip(QCoreApplication::translate("MainWindow", "\351\200\200\345\207\272", nullptr)); 524 | #endif // QT_CONFIG(tooltip) 525 | actVideoStop->setText(QCoreApplication::translate("MainWindow", "\345\201\234\346\255\242\345\275\225\345\203\217", nullptr)); 526 | #if QT_CONFIG(tooltip) 527 | actVideoStop->setToolTip(QCoreApplication::translate("MainWindow", "\345\201\234\346\255\242\345\275\225\345\203\217", nullptr)); 528 | #endif // QT_CONFIG(tooltip) 529 | groupBox_Camera->setTitle(QCoreApplication::translate("MainWindow", "\346\221\204\345\203\217\345\244\264\350\256\276\345\244\207", nullptr)); 530 | label->setText(QCoreApplication::translate("MainWindow", "\346\221\204\345\203\217\345\244\264", nullptr)); 531 | label_3->setText(QCoreApplication::translate("MainWindow", "\346\224\257\346\214\201\347\232\204\346\213\215\347\205\247\345\210\206\350\276\250\347\216\207", nullptr)); 532 | label_2->setText(QCoreApplication::translate("MainWindow", "\346\221\204\345\203\217\345\244\264\344\275\215\347\275\256", nullptr)); 533 | comboCam_Position->setItemText(0, QCoreApplication::translate("MainWindow", "\346\234\252\350\256\276\347\275\256", nullptr)); 534 | comboCam_Position->setItemText(1, QCoreApplication::translate("MainWindow", "\345\220\216\347\275\256", nullptr)); 535 | comboCam_Position->setItemText(2, QCoreApplication::translate("MainWindow", "\345\211\215\347\275\256", nullptr)); 536 | 537 | label_4->setText(QCoreApplication::translate("MainWindow", "\346\224\257\346\214\201\347\232\204\350\247\206\351\242\221\345\210\206\350\276\250\347\216\207", nullptr)); 538 | label_5->setText(QCoreApplication::translate("MainWindow", "\350\247\206\351\242\221\345\270\247\347\216\207\350\214\203\345\233\264", nullptr)); 539 | groupBox_2->setTitle(QCoreApplication::translate("MainWindow", "\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266\347\211\271\346\200\247", nullptr)); 540 | chkBoxCam_Color->setText(QCoreApplication::translate("MainWindow", "ColorTemperature", nullptr)); 541 | chkBoxCam_Manual->setText(QCoreApplication::translate("MainWindow", "ManualExposureTime", nullptr)); 542 | chkBoxCam_Exposure->setText(QCoreApplication::translate("MainWindow", "ExposureCompensation", nullptr)); 543 | chkBoxCam_Custom->setText(QCoreApplication::translate("MainWindow", "CustomFocusPoint", nullptr)); 544 | chkBoxCam_Iso->setText(QCoreApplication::translate("MainWindow", "IsoSensitivity", nullptr)); 545 | chkBoxCam_Focus->setText(QCoreApplication::translate("MainWindow", "FocusDistance", nullptr)); 546 | groupBox->setTitle(QCoreApplication::translate("MainWindow", "\346\221\204\345\203\217\345\244\264\351\242\204\350\247\210", nullptr)); 547 | groupBox_3->setTitle(QCoreApplication::translate("MainWindow", "\346\213\215\347\205\247\350\256\276\347\275\256", nullptr)); 548 | label_6->setText(QCoreApplication::translate("MainWindow", "\345\233\276\347\211\207\347\274\226\347\240\201\345\223\201\350\264\250", nullptr)); 549 | comboImage_Quality->setItemText(0, QCoreApplication::translate("MainWindow", "VeryLowQuality", nullptr)); 550 | comboImage_Quality->setItemText(1, QCoreApplication::translate("MainWindow", "LowQuality", nullptr)); 551 | comboImage_Quality->setItemText(2, QCoreApplication::translate("MainWindow", "NormalQuality", nullptr)); 552 | comboImage_Quality->setItemText(3, QCoreApplication::translate("MainWindow", "HighQuality", nullptr)); 553 | comboImage_Quality->setItemText(4, QCoreApplication::translate("MainWindow", "VeryHighQuality", nullptr)); 554 | 555 | chkBox_Sound->setText(QCoreApplication::translate("MainWindow", "\346\222\255\346\224\276\351\237\263\346\225\210", nullptr)); 556 | label_11->setText(QCoreApplication::translate("MainWindow", "\345\233\276\347\211\207\345\210\206\350\276\250\347\216\207", nullptr)); 557 | chkBox_SaveToFile->setText(QCoreApplication::translate("MainWindow", "\344\277\235\345\255\230\344\270\272\346\226\207\344\273\266", nullptr)); 558 | labImage->setText(QCoreApplication::translate("MainWindow", "\346\213\215\347\205\247\347\232\204\345\233\276\347\211\207", nullptr)); 559 | tabWidget->setTabText(tabWidget->indexOf(tab), QCoreApplication::translate("MainWindow", "\346\213\215\346\221\204\347\232\204\347\205\247\347\211\207", nullptr)); 560 | btnVideoFile->setText(QCoreApplication::translate("MainWindow", "\344\277\235\345\255\230\346\226\207\344\273\266", nullptr)); 561 | editVideo_OutputFile->setText(QString()); 562 | groupBox_5->setTitle(QCoreApplication::translate("MainWindow", "\345\275\225\345\203\217\350\256\276\347\275\256", nullptr)); 563 | label_8->setText(QCoreApplication::translate("MainWindow", "\350\247\206\351\242\221\347\274\226\347\240\201", nullptr)); 564 | label_9->setText(QCoreApplication::translate("MainWindow", "\346\226\207\344\273\266\346\240\274\345\274\217", nullptr)); 565 | label_10->setText(QCoreApplication::translate("MainWindow", "\350\247\206\351\242\221\347\274\226\347\240\201\345\223\201\350\264\250", nullptr)); 566 | comboViedo_Quality->setItemText(0, QCoreApplication::translate("MainWindow", "VeryLowQuality", nullptr)); 567 | comboViedo_Quality->setItemText(1, QCoreApplication::translate("MainWindow", "LowQuality", nullptr)); 568 | comboViedo_Quality->setItemText(2, QCoreApplication::translate("MainWindow", "NormalQuality", nullptr)); 569 | comboViedo_Quality->setItemText(3, QCoreApplication::translate("MainWindow", "HighQuality", nullptr)); 570 | comboViedo_Quality->setItemText(4, QCoreApplication::translate("MainWindow", "VeryHighQuality", nullptr)); 571 | 572 | label_7->setText(QCoreApplication::translate("MainWindow", "\350\247\206\351\242\221\345\210\206\350\276\250\347\216\207", nullptr)); 573 | tabWidget->setTabText(tabWidget->indexOf(tab_2), QCoreApplication::translate("MainWindow", "\345\275\225\345\203\217\350\256\276\347\275\256", nullptr)); 574 | } // retranslateUi 575 | 576 | }; 577 | 578 | namespace Ui { 579 | class MainWindow: public Ui_MainWindow {}; 580 | } // namespace Ui 581 | 582 | QT_END_NAMESPACE 583 | 584 | #endif // UI_MAINWINDOW_H 585 | -------------------------------------------------------------------------------- /qt_source/videoCapture.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | QT += multimedia multimediawidgets 4 | 5 | 6 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 7 | 8 | CONFIG += c++11 9 | 10 | # You can make your code fail to compile if it uses deprecated APIs. 11 | # In order to do so, uncomment the following line. 12 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 13 | 14 | SOURCES += \ 15 | main.cpp \ 16 | mainwindow.cpp 17 | 18 | HEADERS += \ 19 | mainwindow.h 20 | 21 | FORMS += \ 22 | mainwindow.ui 23 | 24 | # Default rules for deployment. 25 | qnx: target.path = /tmp/$${TARGET}/bin 26 | else: unix:!android: target.path = /opt/$${TARGET}/bin 27 | !isEmpty(target.path): INSTALLS += target 28 | 29 | RESOURCES += \ 30 | res.qrc 31 | -------------------------------------------------------------------------------- /qt_source/videoCapture.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {c6d52ced-5c58-4213-95d6-38e1dc37112c} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | false 41 | true 42 | false 43 | 0 44 | true 45 | true 46 | 0 47 | 8 48 | true 49 | false 50 | 1 51 | true 52 | true 53 | true 54 | *.md, *.MD, Makefile 55 | false 56 | true 57 | true 58 | 59 | 60 | 61 | ProjectExplorer.Project.PluginSettings 62 | 63 | 64 | true 65 | false 66 | true 67 | true 68 | true 69 | true 70 | 71 | 72 | 0 73 | true 74 | 75 | true 76 | true 77 | Builtin.DefaultTidyAndClazy 78 | 2 79 | 80 | 81 | 82 | true 83 | 84 | 85 | 86 | 87 | ProjectExplorer.Project.Target.0 88 | 89 | Desktop 90 | Desktop Qt 6.2.4 MinGW 64-bit 91 | Desktop Qt 6.2.4 MinGW 64-bit 92 | qt.qt6.624.win64_mingw_kit 93 | 0 94 | 0 95 | 0 96 | 97 | 0 98 | D:\learning materials\stm32\project\QTDemo\videoCapture 99 | D:/learning materials/QT book/codeExample/Chap16_Multimedia/build-videoCapture-Desktop_Qt_6_2_4_MinGW_64_bit-Debug 100 | 101 | 102 | true 103 | QtProjectManager.QMakeBuildStep 104 | false 105 | 106 | 107 | 108 | true 109 | Qt4ProjectManager.MakeStep 110 | 111 | 2 112 | 构建 113 | 构建 114 | ProjectExplorer.BuildSteps.Build 115 | 116 | 117 | 118 | true 119 | Qt4ProjectManager.MakeStep 120 | clean 121 | 122 | 1 123 | 清除 124 | 清除 125 | ProjectExplorer.BuildSteps.Clean 126 | 127 | 2 128 | false 129 | 130 | false 131 | 132 | Debug 133 | Qt4ProjectManager.Qt4BuildConfiguration 134 | 2 135 | 136 | 137 | D:\learning materials\QT book\codeExample\Chap16_Multimedia\build-videoCapture-Desktop_Qt_6_2_4_MinGW_64_bit-Release 138 | D:/learning materials/QT book/codeExample/Chap16_Multimedia/build-videoCapture-Desktop_Qt_6_2_4_MinGW_64_bit-Release 139 | 140 | 141 | true 142 | QtProjectManager.QMakeBuildStep 143 | false 144 | 145 | 146 | 147 | true 148 | Qt4ProjectManager.MakeStep 149 | 150 | 2 151 | 构建 152 | 构建 153 | ProjectExplorer.BuildSteps.Build 154 | 155 | 156 | 157 | true 158 | Qt4ProjectManager.MakeStep 159 | clean 160 | 161 | 1 162 | 清除 163 | 清除 164 | ProjectExplorer.BuildSteps.Clean 165 | 166 | 2 167 | false 168 | 169 | false 170 | 171 | Release 172 | Qt4ProjectManager.Qt4BuildConfiguration 173 | 0 174 | 0 175 | 176 | 177 | 0 178 | D:\learning materials\QT book\codeExample\Chap16_Multimedia\build-videoCapture-Desktop_Qt_6_2_4_MinGW_64_bit-Profile 179 | D:/learning materials/QT book/codeExample/Chap16_Multimedia/build-videoCapture-Desktop_Qt_6_2_4_MinGW_64_bit-Profile 180 | 181 | 182 | true 183 | QtProjectManager.QMakeBuildStep 184 | false 185 | 186 | 187 | 188 | true 189 | Qt4ProjectManager.MakeStep 190 | 191 | 2 192 | 构建 193 | 构建 194 | ProjectExplorer.BuildSteps.Build 195 | 196 | 197 | 198 | true 199 | Qt4ProjectManager.MakeStep 200 | clean 201 | 202 | 1 203 | 清除 204 | 清除 205 | ProjectExplorer.BuildSteps.Clean 206 | 207 | 2 208 | false 209 | 210 | false 211 | 212 | Profile 213 | Qt4ProjectManager.Qt4BuildConfiguration 214 | 0 215 | 0 216 | 0 217 | 218 | 3 219 | 220 | 221 | 0 222 | 部署 223 | 部署 224 | ProjectExplorer.BuildSteps.Deploy 225 | 226 | 1 227 | 228 | false 229 | ProjectExplorer.DefaultDeployConfiguration 230 | 231 | 1 232 | 233 | true 234 | true 235 | true 236 | 237 | 2 238 | 239 | videoCapture2 240 | Qt4ProjectManager.Qt4RunConfiguration:D:/learning materials/stm32/project/QTDemo/videoCapture/videoCapture.pro 241 | D:/learning materials/stm32/project/QTDemo/videoCapture/videoCapture.pro 242 | false 243 | true 244 | true 245 | false 246 | true 247 | D:/learning materials/stm32/project/QTDemo/videoCapture 248 | 249 | 1 250 | 251 | 252 | 253 | ProjectExplorer.Project.TargetCount 254 | 1 255 | 256 | 257 | ProjectExplorer.Project.Updater.FileVersion 258 | 22 259 | 260 | 261 | Version 262 | 22 263 | 264 | 265 | -------------------------------------------------------------------------------- /render/Makefile: -------------------------------------------------------------------------------- 1 | obj-y += operation/ 2 | -------------------------------------------------------------------------------- /render/operation/Makefile: -------------------------------------------------------------------------------- 1 | obj-y += zoom.o 2 | obj-y += merge.o 3 | 4 | -------------------------------------------------------------------------------- /render/operation/merge.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | /*图片合并**/ 6 | int PicMerge(int iX, int iY, PT_PixelDatas ptSmallPic, PT_PixelDatas ptBigPic) 7 | { 8 | int i; 9 | unsigned char *pucSrc; 10 | unsigned char *pucDst; 11 | 12 | if ((ptSmallPic->iWidth > ptBigPic->iWidth) || 13 | (ptSmallPic->iHeight > ptBigPic->iHeight) || 14 | (ptSmallPic->iBpp != ptBigPic->iBpp)) 15 | { 16 | return -1; 17 | } 18 | 19 | pucSrc = ptSmallPic->aucPixelDatas; 20 | pucDst = ptBigPic->aucPixelDatas + iY * ptBigPic->iLineBytes + iX * ptBigPic->iBpp / 8; 21 | for (i = 0; i < ptSmallPic->iHeight; i++) 22 | { 23 | memcpy(pucDst, pucSrc, ptSmallPic->iLineBytes); 24 | pucSrc += ptSmallPic->iLineBytes; 25 | pucDst += ptBigPic->iLineBytes; 26 | } 27 | return 0; 28 | } 29 | 30 | 31 | /** **/ 32 | int PicMergeRegion(int iStartXofNewPic, int iStartYofNewPic, int iStartXofOldPic, int iStartYofOldPic, int iWidth, int iHeight, PT_PixelDatas ptNewPic, PT_PixelDatas ptOldPic) 33 | { 34 | int i; 35 | unsigned char *pucSrc; 36 | unsigned char *pucDst; 37 | int iLineBytesCpy = iWidth * ptNewPic->iBpp / 8; 38 | 39 | if ((iStartXofNewPic < 0 || iStartXofNewPic >= ptNewPic->iWidth) || \ 40 | (iStartYofNewPic < 0 || iStartYofNewPic >= ptNewPic->iHeight) || \ 41 | (iStartXofOldPic < 0 || iStartXofOldPic >= ptOldPic->iWidth) || \ 42 | (iStartYofOldPic < 0 || iStartYofOldPic >= ptOldPic->iHeight)) 43 | { 44 | return -1; 45 | } 46 | 47 | pucSrc = ptNewPic->aucPixelDatas + iStartYofNewPic * ptNewPic->iLineBytes + iStartXofNewPic * ptNewPic->iBpp / 8; 48 | pucDst = ptOldPic->aucPixelDatas + iStartYofOldPic * ptOldPic->iLineBytes + iStartXofOldPic * ptOldPic->iBpp / 8; 49 | for (i = 0; i < iHeight; i++) 50 | { 51 | memcpy(pucDst, pucSrc, iLineBytesCpy); 52 | pucSrc += ptNewPic->iLineBytes; 53 | pucDst += ptOldPic->iLineBytes; 54 | } 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /render/operation/zoom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | /* 缩放图片 **/ 8 | int PicZoom(PT_PixelDatas ptOriginPic, PT_PixelDatas ptZoomPic) 9 | { 10 | unsigned long dwDstWidth = ptZoomPic->iWidth; 11 | unsigned long* pdwSrcXTable; 12 | unsigned long x; 13 | unsigned long y; 14 | unsigned long dwSrcY; 15 | unsigned char *pucDest; 16 | unsigned char *pucSrc; 17 | unsigned long dwPixelBytes = ptOriginPic->iBpp/8; 18 | 19 | DBG_PRINTF("src:\n"); 20 | DBG_PRINTF("%d x %d, %d bpp, data: 0x%x\n", ptOriginPic->iWidth, ptOriginPic->iHeight, ptOriginPic->iBpp, (unsigned int)ptOriginPic->aucPixelDatas); 21 | 22 | DBG_PRINTF("dest:\n"); 23 | DBG_PRINTF("%d x %d, %d bpp, data: 0x%x\n", ptZoomPic->iWidth, ptZoomPic->iHeight, ptZoomPic->iBpp, (unsigned int)ptZoomPic->aucPixelDatas); 24 | 25 | if (ptOriginPic->iBpp != ptZoomPic->iBpp) 26 | { 27 | return -1; 28 | } 29 | 30 | pdwSrcXTable = malloc(sizeof(unsigned long) * dwDstWidth); 31 | if (NULL == pdwSrcXTable) 32 | { 33 | DBG_PRINTF("malloc error!\n"); 34 | return -1; 35 | } 36 | 37 | for (x = 0; x < dwDstWidth; x++) 38 | { 39 | pdwSrcXTable[x]=(x*ptOriginPic->iWidth/ptZoomPic->iWidth); 40 | } 41 | 42 | for (y = 0; y < ptZoomPic->iHeight; y++) 43 | { 44 | dwSrcY = (y * ptOriginPic->iHeight / ptZoomPic->iHeight); 45 | 46 | pucDest = ptZoomPic->aucPixelDatas + y*ptZoomPic->iLineBytes; 47 | pucSrc = ptOriginPic->aucPixelDatas + dwSrcY*ptOriginPic->iLineBytes; 48 | 49 | for (x = 0; x 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | -------------------------------------------------------------------------------- /video/v4l2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static int g_aiSupportedFormats[] = {V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_RGB565}; 15 | 16 | static int V4l2GetFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf); 17 | static int V4l2PutFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf); 18 | static T_VideoOpr g_tV4l2VideoOpr; 19 | 20 | static int isSupportThisFormat(int iPixelFormat) 21 | { 22 | int i; 23 | for (i = 0; i < sizeof(g_aiSupportedFormats)/sizeof(g_aiSupportedFormats[0]); i++) 24 | { 25 | if (g_aiSupportedFormats[i] == iPixelFormat) 26 | return 1; 27 | } 28 | return 0; 29 | } 30 | 31 | /*参考 luvcview */ 32 | 33 | /* open 34 | * VIDIOC_QUERYCAP 判断表名是摄像头设备(streaming/read,write) 35 | * VIDIOC_ENUM_FMT 列举摄像头数据格式 36 | * VIDIOC_S_FMT 设置数据格式ʽ 37 | * VIDIOC_REQBUFS 申请buffer 38 | 对于 streaming: 39 | * VIDIOC_QUERYBUF 申请buffe , mmap 40 | * VIDIOC_QBUF 将数据放入队列命令 41 | * VIDIOC_STREAMON 开启 42 | * poll 43 | * VIDIOC_DQBUF 将数据取出队列 44 | * 循环.... 45 | * VIDIOC_QBUF 放入队列 46 | * .... 47 | 对于 read,write: 48 | read 49 | .... 50 | read 51 | * VIDIOC_STREAMOFF ֹͣ关闭设备 52 | * 53 | */ 54 | 55 | static int V4l2InitDevice(char *strDevName, PT_VideoDevice ptVideoDevice) 56 | { 57 | int i; 58 | int iFd; 59 | int iError; 60 | struct v4l2_capability tV4l2Cap; 61 | struct v4l2_fmtdesc tFmtDesc; 62 | struct v4l2_format tV4l2Fmt; 63 | struct v4l2_requestbuffers tV4l2ReqBuffs; 64 | struct v4l2_buffer tV4l2Buf; 65 | 66 | int iLcdWidth; 67 | int iLcdHeigt; 68 | int iLcdBpp; 69 | 70 | iFd = open(strDevName, O_RDWR); 71 | if (iFd < 0) 72 | { 73 | DBG_PRINTF("can not open %s\n", strDevName); 74 | return -1; 75 | } 76 | ptVideoDevice->iFd = iFd; 77 | 78 | /*判断是摄像头设备*/ 79 | iError = ioctl(iFd, VIDIOC_QUERYCAP, &tV4l2Cap); 80 | memset(&tV4l2Cap, 0, sizeof(struct v4l2_capability)); 81 | iError = ioctl(iFd, VIDIOC_QUERYCAP, &tV4l2Cap); 82 | if (iError) { 83 | DBG_PRINTF("Error opening device %s: unable to query device.\n", strDevName); 84 | goto err_exit; 85 | } 86 | 87 | /*如果不是摄像头拍摄*/ 88 | if (!(tV4l2Cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) 89 | { 90 | DBG_PRINTF("%s is not a video capture device\n", strDevName); 91 | goto err_exit; 92 | } 93 | 94 | if (tV4l2Cap.capabilities & V4L2_CAP_STREAMING) { 95 | DBG_PRINTF("%s supports streaming i/o\n", strDevName); 96 | } 97 | 98 | if (tV4l2Cap.capabilities & V4L2_CAP_READWRITE) { 99 | DBG_PRINTF("%s supports read i/o\n", strDevName); 100 | } 101 | 102 | memset(&tFmtDesc, 0, sizeof(tFmtDesc)); 103 | tFmtDesc.index = 0; 104 | tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 105 | while ((iError = ioctl(iFd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) { 106 | if (isSupportThisFormat(tFmtDesc.pixelformat)) 107 | { 108 | ptVideoDevice->iPixelFormat = tFmtDesc.pixelformat; 109 | break; 110 | } 111 | tFmtDesc.index++; 112 | } 113 | 114 | if (!ptVideoDevice->iPixelFormat) 115 | { 116 | DBG_PRINTF("can not support the format of this device\n"); 117 | goto err_exit; 118 | } 119 | 120 | 121 | /* set format in */ 122 | GetDispResolution(&iLcdWidth, &iLcdHeigt, &iLcdBpp); 123 | memset(&tV4l2Fmt, 0, sizeof(struct v4l2_format)); 124 | tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 125 | tV4l2Fmt.fmt.pix.pixelformat = ptVideoDevice->iPixelFormat; 126 | tV4l2Fmt.fmt.pix.width = iLcdWidth; 127 | tV4l2Fmt.fmt.pix.height = iLcdHeigt; 128 | tV4l2Fmt.fmt.pix.field = V4L2_FIELD_ANY; 129 | 130 | /* 如果驱动程序发现无法设置某些参数(比如分辨率), 131 | * 它会调整这些参数, 并且返回给应用程序 132 | */ 133 | /*设置摄像头数据格式*/ 134 | iError = ioctl(iFd, VIDIOC_S_FMT, &tV4l2Fmt); 135 | if (iError) 136 | { 137 | DBG_PRINTF("Unable to set format\n"); 138 | goto err_exit; 139 | } 140 | ptVideoDevice->iWidth = tV4l2Fmt.fmt.pix.width; 141 | ptVideoDevice->iHeight = tV4l2Fmt.fmt.pix.height; 142 | 143 | /* request buffers */ 144 | memset(&tV4l2ReqBuffs, 0, sizeof(struct v4l2_requestbuffers)); 145 | tV4l2ReqBuffs.count = NB_BUFFER; 146 | tV4l2ReqBuffs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 147 | tV4l2ReqBuffs.memory = V4L2_MEMORY_MMAP; 148 | 149 | iError = ioctl(iFd, VIDIOC_REQBUFS, &tV4l2ReqBuffs); 150 | if (iError) 151 | { 152 | DBG_PRINTF("Unable to allocate buffers.\n"); 153 | goto err_exit; 154 | } 155 | 156 | /*vidioc_g_fmt_vid_cap*/ 157 | 158 | ptVideoDevice->iVideoBufCnt = tV4l2ReqBuffs.count; 159 | if (tV4l2Cap.capabilities & V4L2_CAP_STREAMING) 160 | { 161 | /* map the buffers */ 162 | for (i = 0; i < ptVideoDevice->iVideoBufCnt; i++) 163 | { 164 | memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer)); 165 | tV4l2Buf.index = i; 166 | tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 167 | tV4l2Buf.memory = V4L2_MEMORY_MMAP; 168 | iError = ioctl(iFd, VIDIOC_QUERYBUF, &tV4l2Buf); 169 | if (iError) 170 | { 171 | DBG_PRINTF("Unable to query buffer.\n"); 172 | goto err_exit; 173 | } 174 | 175 | ptVideoDevice->iVideoBufMaxLen = tV4l2Buf.length; 176 | ptVideoDevice->pucVideBuf[i] = mmap(0 /* start anywhere */ , 177 | tV4l2Buf.length, PROT_READ, MAP_SHARED, iFd, 178 | tV4l2Buf.m.offset); 179 | if (ptVideoDevice->pucVideBuf[i] == MAP_FAILED) 180 | { 181 | DBG_PRINTF("Unable to map buffer\n"); 182 | goto err_exit; 183 | } 184 | } 185 | 186 | /* Queue the buffers. */ 187 | for (i = 0; i < ptVideoDevice->iVideoBufCnt; i++) 188 | { 189 | memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer)); 190 | tV4l2Buf.index = i; 191 | tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 192 | tV4l2Buf.memory = V4L2_MEMORY_MMAP; 193 | iError = ioctl(iFd, VIDIOC_QBUF, &tV4l2Buf); 194 | if (iError) 195 | { 196 | DBG_PRINTF("Unable to queue buffer.\n"); 197 | goto err_exit; 198 | } 199 | } 200 | 201 | } 202 | else if (tV4l2Cap.capabilities & V4L2_CAP_READWRITE) 203 | { 204 | g_tV4l2VideoOpr.GetFrame = V4l2GetFrameForReadWrite; 205 | g_tV4l2VideoOpr.PutFrame = V4l2PutFrameForReadWrite; 206 | 207 | /* read(fd, buf, size) */ 208 | ptVideoDevice->iVideoBufCnt = 1; 209 | 210 | /* 在这个程序所能支持的格式里, 一个像素最多只需要4字节 */ 211 | ptVideoDevice->iVideoBufMaxLen = ptVideoDevice->iWidth * ptVideoDevice->iHeight * 4; 212 | ptVideoDevice->pucVideBuf[0] = malloc(ptVideoDevice->iVideoBufMaxLen); 213 | } 214 | 215 | ptVideoDevice->ptOPr = &g_tV4l2VideoOpr; 216 | return 0; 217 | 218 | err_exit: 219 | close(iFd); 220 | return -1; 221 | } 222 | 223 | static int V4l2ExitDevice(PT_VideoDevice ptVideoDevice) 224 | { 225 | int i; 226 | for (i = 0; i < ptVideoDevice->iVideoBufCnt; i++) 227 | { 228 | if (ptVideoDevice->pucVideBuf[i]) 229 | { 230 | munmap(ptVideoDevice->pucVideBuf[i], ptVideoDevice->iVideoBufMaxLen); 231 | ptVideoDevice->pucVideBuf[i] = NULL; 232 | } 233 | } 234 | 235 | close(ptVideoDevice->iFd); 236 | return 0; 237 | } 238 | 239 | /*获取数据流的数据格式*/ 240 | static int V4l2GetFrameForStreaming(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) 241 | { 242 | struct pollfd tFds[1]; 243 | int iRet; 244 | struct v4l2_buffer tV4l2Buf; 245 | 246 | /* poll */ 247 | tFds[0].fd = ptVideoDevice->iFd; 248 | tFds[0].events = POLLIN; 249 | 250 | iRet = poll(tFds, 1, -1); 251 | if (iRet <= 0) 252 | { 253 | DBG_PRINTF("poll error!\n"); 254 | return -1; 255 | } 256 | 257 | /* VIDIOC_DQBUF */ 258 | memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer)); 259 | tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 260 | tV4l2Buf.memory = V4L2_MEMORY_MMAP; 261 | iRet = ioctl(ptVideoDevice->iFd, VIDIOC_DQBUF, &tV4l2Buf); 262 | if (iRet < 0) 263 | { 264 | DBG_PRINTF("Unable to dequeue buffer.\n"); 265 | return -1; 266 | } 267 | ptVideoDevice->iVideoBufCurIndex = tV4l2Buf.index; 268 | 269 | ptVideoBuf->iPixelFormat = ptVideoDevice->iPixelFormat; 270 | ptVideoBuf->tPixelDatas.iWidth = ptVideoDevice->iWidth; 271 | ptVideoBuf->tPixelDatas.iHeight = ptVideoDevice->iHeight; 272 | ptVideoBuf->tPixelDatas.iBpp = (ptVideoDevice->iPixelFormat == V4L2_PIX_FMT_YUYV) ? 16 : \ 273 | (ptVideoDevice->iPixelFormat == V4L2_PIX_FMT_MJPEG) ? 0 : \ 274 | (ptVideoDevice->iPixelFormat == V4L2_PIX_FMT_RGB565) ? 16 : \ 275 | 0; 276 | ptVideoBuf->tPixelDatas.iLineBytes = ptVideoDevice->iWidth * ptVideoBuf->tPixelDatas.iBpp / 8; 277 | ptVideoBuf->tPixelDatas.iTotalBytes = tV4l2Buf.bytesused; 278 | ptVideoBuf->tPixelDatas.aucPixelDatas = ptVideoDevice->pucVideBuf[tV4l2Buf.index]; 279 | return 0; 280 | } 281 | 282 | 283 | static int V4l2PutFrameForStreaming(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) 284 | { 285 | /* VIDIOC_QBUF */ 286 | struct v4l2_buffer tV4l2Buf; 287 | int iError; 288 | 289 | memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer)); 290 | tV4l2Buf.index = ptVideoDevice->iVideoBufCurIndex; 291 | tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 292 | tV4l2Buf.memory = V4L2_MEMORY_MMAP; 293 | iError = ioctl(ptVideoDevice->iFd, VIDIOC_QBUF, &tV4l2Buf); 294 | if (iError) 295 | { 296 | DBG_PRINTF("Unable to queue buffer.\n"); 297 | return -1; 298 | } 299 | return 0; 300 | } 301 | 302 | static int V4l2GetFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) 303 | { 304 | int iRet; 305 | 306 | iRet = read(ptVideoDevice->iFd, ptVideoDevice->pucVideBuf[0], ptVideoDevice->iVideoBufMaxLen); 307 | if (iRet <= 0) 308 | { 309 | return -1; 310 | } 311 | 312 | ptVideoBuf->iPixelFormat = ptVideoDevice->iPixelFormat; 313 | ptVideoBuf->tPixelDatas.iWidth = ptVideoDevice->iWidth; 314 | ptVideoBuf->tPixelDatas.iHeight = ptVideoDevice->iHeight; 315 | ptVideoBuf->tPixelDatas.iBpp = (ptVideoDevice->iPixelFormat == V4L2_PIX_FMT_YUYV) ? 16 : \ 316 | (ptVideoDevice->iPixelFormat == V4L2_PIX_FMT_MJPEG) ? 0 : \ 317 | (ptVideoDevice->iPixelFormat == V4L2_PIX_FMT_RGB565)? 16 : \ 318 | 0; 319 | ptVideoBuf->tPixelDatas.iLineBytes = ptVideoDevice->iWidth * ptVideoBuf->tPixelDatas.iBpp / 8; 320 | ptVideoBuf->tPixelDatas.iTotalBytes = iRet; 321 | ptVideoBuf->tPixelDatas.aucPixelDatas = ptVideoDevice->pucVideBuf[0]; 322 | 323 | return 0; 324 | } 325 | 326 | 327 | static int V4l2PutFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) 328 | { 329 | return 0; 330 | } 331 | 332 | static int V4l2StartDevice(PT_VideoDevice ptVideoDevice) 333 | { 334 | int iType = V4L2_BUF_TYPE_VIDEO_CAPTURE; 335 | int iError; 336 | 337 | iError = ioctl(ptVideoDevice->iFd, VIDIOC_STREAMON, &iType); 338 | if (iError) 339 | { 340 | DBG_PRINTF("Unable to start capture.\n"); 341 | return -1; 342 | } 343 | return 0; 344 | } 345 | 346 | static int V4l2StopDevice(PT_VideoDevice ptVideoDevice) 347 | { 348 | int iType = V4L2_BUF_TYPE_VIDEO_CAPTURE; 349 | int iError; 350 | 351 | iError = ioctl(ptVideoDevice->iFd, VIDIOC_STREAMOFF, &iType); 352 | if (iError) 353 | { 354 | DBG_PRINTF("Unable to stop capture.\n"); 355 | return -1; 356 | } 357 | return 0; 358 | } 359 | 360 | static int V4l2GetFormat(PT_VideoDevice ptVideoDevice) 361 | { 362 | return ptVideoDevice->iPixelFormat; 363 | } 364 | 365 | 366 | /* 构造 VideoOp 结构体 */ 367 | static T_VideoOpr g_tV4l2VideoOpr = { 368 | .name = "v4l2", 369 | .InitDevice = V4l2InitDevice, 370 | .ExitDevice = V4l2ExitDevice, 371 | .GetFormat = V4l2GetFormat, 372 | .GetFrame = V4l2GetFrameForStreaming, 373 | .PutFrame = V4l2PutFrameForStreaming, 374 | .StartDevice = V4l2StartDevice, 375 | .StopDevice = V4l2StopDevice, 376 | }; 377 | 378 | /* 初始化 */ 379 | int V4l2Init(void) 380 | { 381 | return RegisterVideoOpr(&g_tV4l2VideoOpr); 382 | } 383 | 384 | -------------------------------------------------------------------------------- /video/video_manager.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static PT_VideoOpr g_ptVideoOprHead = NULL; 6 | 7 | /* RegisterVideoOpr*/ 8 | int RegisterVideoOpr(PT_VideoOpr ptVideoOpr) 9 | { 10 | PT_VideoOpr ptTmp; 11 | 12 | if (!g_ptVideoOprHead) 13 | { 14 | g_ptVideoOprHead = ptVideoOpr; 15 | ptVideoOpr->ptNext = NULL; 16 | } 17 | else 18 | { 19 | ptTmp = g_ptVideoOprHead; 20 | while (ptTmp->ptNext) 21 | { 22 | ptTmp = ptTmp->ptNext; 23 | } 24 | ptTmp->ptNext = ptVideoOpr; 25 | ptVideoOpr->ptNext = NULL; 26 | } 27 | 28 | return 0; 29 | } 30 | 31 | 32 | /*显示能支持的字体模块**/ 33 | void ShowVideoOpr(void) 34 | { 35 | int i = 0; 36 | PT_VideoOpr ptTmp = g_ptVideoOprHead; 37 | 38 | while (ptTmp) 39 | { 40 | printf("%02d %s\n", i++, ptTmp->name); 41 | ptTmp = ptTmp->ptNext; 42 | } 43 | } 44 | 45 | /* 根据 pcName 取出指定的字体模块*/ 46 | PT_VideoOpr GetVideoOpr(char *pcName) 47 | { 48 | PT_VideoOpr ptTmp = g_ptVideoOprHead; 49 | 50 | while (ptTmp) 51 | { 52 | if (strcmp(ptTmp->name, pcName) == 0) 53 | { 54 | return ptTmp; 55 | } 56 | ptTmp = ptTmp->ptNext; 57 | } 58 | return NULL; 59 | } 60 | 61 | int VideoDeviceInit(char *strDevName, PT_VideoDevice ptVideoDevice) 62 | { 63 | int iError; 64 | PT_VideoOpr ptTmp = g_ptVideoOprHead; 65 | 66 | while (ptTmp) 67 | { 68 | iError = ptTmp->InitDevice(strDevName, ptVideoDevice); 69 | if (!iError) 70 | { 71 | return 0; 72 | } 73 | ptTmp = ptTmp->ptNext; 74 | } 75 | return -1; 76 | } 77 | 78 | /* 调用各个字体模块的初始化函数*/ 79 | int VideoInit(void) 80 | { 81 | int iError; 82 | 83 | iError = V4l2Init(); 84 | 85 | return iError; 86 | } 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /演示/QT6摄像头界面/QT6界面演示.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/演示/QT6摄像头界面/QT6界面演示.mp4 -------------------------------------------------------------------------------- /演示/QT6摄像头界面/演示1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/演示/QT6摄像头界面/演示1.jpg -------------------------------------------------------------------------------- /演示/QT6摄像头界面/演示2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/演示/QT6摄像头界面/演示2.jpg -------------------------------------------------------------------------------- /演示/USB摄像头驱动展示/图片展示1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/演示/USB摄像头驱动展示/图片展示1.jpg -------------------------------------------------------------------------------- /演示/USB摄像头驱动展示/图片展示2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/演示/USB摄像头驱动展示/图片展示2.jpg -------------------------------------------------------------------------------- /演示/USB摄像头驱动展示/监控实景展示.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhu-hao-jie/VideoSurveillance/27b0e82a2b094a2b1e797b83c982c2f4953d6564/演示/USB摄像头驱动展示/监控实景展示.mp4 --------------------------------------------------------------------------------