📄 sp54convert.c
字号:
/** * SP54convert: Simple SP54 codec converter to MJPG. * * Testing tool for the spca50x based cams. Made and copyrighted * by Michel Xhaard, Till Adam june in 2003. * * With the help of avilib Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.**/#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "avilib.h"#include "spca50x-jpeg-header.h"/* Pascal come back */voidwriteln_fatal (char *msg){ printf ("%s \n", msg); exit (1);}static voidcreate_jpeg_from_data (u_int8_t * dst, u_int8_t * src, int qIndex, int w, int h, u_int8_t format, int o_size, int *size, int omit_huffman_table, int omit_escape){ int i = 0; u_int8_t *start; u_int8_t value; start = dst; /* copy the header from the template */ memcpy (dst, SPCA50xJPGDefaultHeaderPart1, SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH); /* modify quantization table */ memcpy (dst + 7, SPCA50xQTable[qIndex * 2], 64); memcpy (dst + 72, SPCA50xQTable[qIndex * 2 + 1], 64); dst += SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH; /* copy Huffman table */ if (!omit_huffman_table) { memcpy (dst, SPCA50xJPGDefaultHeaderPart2, SPCA50X_JPG_DEFAULT_HEADER_PART2_LENGTH); dst += SPCA50X_JPG_DEFAULT_HEADER_PART2_LENGTH; } memcpy (dst, SPCA50xJPGDefaultHeaderPart3, SPCA50X_JPG_DEFAULT_HEADER_PART3_LENGTH); /* modify the image width, height */ *(dst + 8) = w & 0xFF; //Image width low byte *(dst + 7) = w >> 8 & 0xFF; //Image width high byte *(dst + 6) = h & 0xFF; //Image height low byte *(dst + 5) = h >> 8 & 0xFF; //Image height high byte /* set the format */ *(dst + 11) = format; /* point to real JPG compress data start position and copy */ dst += SPCA50X_JPG_DEFAULT_HEADER_PART3_LENGTH; for (i = 0; i < o_size; i++) { value = *(src + i) & 0xFF; *(dst) = value; dst++; if (value == 0xFF && !omit_escape) { *(dst) = 0x00; dst++; } } /* Add end of image marker */ *(dst++) = 0xFF; *(dst++) = 0xD9; *size = dst - start;}intmain (int ac, char **av){ avi_t *aviinput, *avioutput; long frames, width, height, audiochannels; long audiobits, audioformat, audiorate, audiobytes, audiosamps, audiobps; double framerate; char *compressor; long i, sizein; long realsize; void *bufferin = NULL; void *data = NULL; unsigned char *pt_bufferin; unsigned char val, probcount; int sizeout; if (ac <= 2) { writeln_fatal ("usage: sp54convert InFILE OutFILE"); } if ((aviinput = AVI_open_input_file (av[1], 1)) == NULL) { writeln_fatal ("Can't read avi file"); } if ((avioutput = AVI_open_output_file (av[2])) == NULL) { writeln_fatal ("Can't write avi file"); } frames = AVI_video_frames (aviinput); audiobytes = AVI_audio_bytes (aviinput); width = AVI_video_width (aviinput); height = AVI_video_height (aviinput); printf ("frame: %d audio: %d width: %d height: %d \n", frames, audiobytes, width, height); framerate = AVI_frame_rate (aviinput); printf (" framerate : %f \n", framerate); compressor = AVI_video_compressor (aviinput); printf (" codec: %s \n", compressor); audiochannels = AVI_audio_channels (aviinput); audiobits = AVI_audio_bits (aviinput); audioformat = AVI_audio_format (aviinput); audiorate = AVI_audio_rate (aviinput); printf ("audiobits: %d audioformat: %d audiorate: %d audiochannels: %d \n", audiobits, audioformat, audiorate, audiochannels); if (strncasecmp (compressor, "SP54", 4) == 0) { /* well we have to do now */ AVI_set_video (avioutput, width, height, framerate, "MJPG"); //AVI_set_audio (avioutput, audiochannels,audiorate,audiobits,audioformat); /* the output header is clean now */ /* Now read all frame create jpeg and write */ printf (" setaudio video done \n"); /* Read frame remove extra data create jpeg data and write frame */ for (i = 0; i < frames; i++) { sizein = AVI_frame_size (aviinput, i); bufferin = (unsigned char *) realloc (bufferin, (size_t) sizein); sizeout = sizein + 8192; data = (unsigned char *) realloc (data, (size_t) sizeout); printf ("-------------------------------- \n"); printf (" sizein %d index: %d \n", sizein, i); if (AVI_read_frame (aviinput, (unsigned char *) bufferin) < 0) printf ("Read error frames %d \n", i); /* now compute the real size */ /* cut the strange bytes at buffer end */ pt_bufferin = (unsigned char *) bufferin + sizein; probcount = 0; val = *pt_bufferin; while (pt_bufferin > (unsigned char *) bufferin) { if (val != 0x00) { if (val == 0xFF) probcount++; else { if (probcount == 6 || probcount == 2) { printf ("skipvalue %0x \n", val); pt_bufferin--; } break; } } val = *pt_bufferin--; } /* now cut the bad header */ realsize = pt_bufferin - (unsigned char *) bufferin - 14; pt_bufferin = bufferin + 14; printf ("realsize %d probcount %d \n", realsize, probcount); printf ("-------------------------------- \n"); create_jpeg_from_data ((unsigned char *) data, pt_bufferin, 5, width, height, 0x22, realsize, &sizeout, 1, 0); if (AVI_write_frame (avioutput, (unsigned char *) data, sizeout) < 0) printf ("write error on avi out %d ", i); } if (bufferin != NULL) free (bufferin); if (data != NULL) free (data); AVI_close (aviinput); AVI_close (avioutput); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -