Simple JPEG to convert to AVI

xiaoxiao2021-03-06  49

This is a small class written by the author to convert a series of JPEG files to AVI. First, put the source code:

//Aviformt.h#ifndef _avi_format_h_ # define _avi_format_h_

#include

Using namespace std;

/ * 4 BYTES * / TYPEDEF INT WORD INT DWORD;

/ * For use in AVI_avih.flags * / const DWORD AVIF_HASINDEX = 0x00000010; / * index at end of file * / const DWORD AVIF_MUSTUSEINDEX = 0x00000020; const DWORD AVIF_ISINTERLEAVED = 0x00000100; const DWORD AVIF_TRUSTCKTYPE = 0x00000800; const DWORD AVIF_WASCAPTUREFILE = 0x00010000; const DWORD AVIF_COPYRIGHTED = 0x00020000;

struct AVI_avih {DWORD usec_per_frame; // * frame display rate (or 0L) * / DWORD max_bytes_per_sec;. // * max transfer rate * / DWORD padding; // * pad to multiples of this size; * / / * normally 2K * / DWORD flags; dword tot_frames; // * # frames in file * / dword init_frames; dWord streams; dword buff_sz; dword width; dword; dword reserved [4]; DWORD RESERVED [4];

AVI_avih () {} AVI_avih (DWORD usec, DWORD max, DWORD pad, DWORD flags, DWORD tot, DWORD init, DWORD str, DWORD buff, DWORD w, DWORD h, DWORD * re = NULL): usec_per_frame (usec), max_bytes_per_sec (MAX), Padding (PAD), INIT_FRAMES (INIT), STREAMS (STR), BUFF_SZ (BUF), Width (W), Height (H) {IF (Re! = NULL) FOR (INT i = 0; i <4; i) reserved [i] = re [i]; else for (int i = 0; i <4; i) reserved [i] = 0;} avi_avih (avi_avih const & avih ) {Usec_per_frame = avih.usec_per_frame; MAX_BYTES_PER_SEC = avih.max_bytes_per_sec; padding = avih.padding;

flags = avih.flags; tot_frames = avih.tot_frames; init_frames = avih.init_frames; streams = avih.streams; buff_sz = avih.buff_sz; width = avih.width; height = avih.height; for (int i; i <4 ; i) reserved [i] = avih.reserved [i];} ~ AVI_avih () {} friend ostream & operator << (ostream & out, AVI_avih const & avih) {out << avih.usec_per_frame << avih.max_bytes_per_sec <

Struct avi_strh {unsigned char Type [4]; /// * stream type * / unsigned char handler [4]; dword flag; dword priority; dword init_frames; /// * initial frames (???) * / dword scale; DWord Rate; DWord LENGTH; DWORD BUFF_SZ; //// * suggester; dword sample_sz;

AVI_STRH () {} AVI_STRH (Char Const * T, CHAR Const * H, DWORD F, DWORD P, DWORD IN, DWORD SC, DWORD R, DWORD ST, DWORD L, DWORD BS, DWORD Q, DWORD SS): Flags f), Priority (P), INIT_FRAMES (IN), Scale (SC), Rate (R), START (ST), LENGTH (L), Buff_sz (BS), Quality (q), Sample_SZ (SS) {for ( INT i = 0; i <4; i) {type [i] = t [i]; handler [i] = h [i];}} avi_strh (avi_strh const & strh) {flags = strh.flags; priority = strh.priority; init_frames = strh.init_frames; scale = strh.scale; rate = strh.rate; start = strh.start; length = strh.length; buff_sz = strh.buff_sz; quality = strh.quality; sample_sz = strh .sample_sz; for (int i = 0; i <4; i) {type [i] = strh.type [i]; handler [i] = strh.handler [i];}} ~ avi_strh ()} } Friend Ostream & Operator << (Ostream & Out, Avi_Strh Const & Strh) {OUT << strH.type [0] << strH.type [1] << strH.type [2] << strH.type [3]; OUT << strH.handler [0] << strH.handler [1] << strH.handler [2] << strH.handler [3]; out << strH.Flags << strH.pr IORITY << strH.init_frames << strH.scale << strH.rate; out << strH.start << strH.Length << strH.buff_sz << strH.quality << strH.sample_sz; return out;}};

struct AVI_strf {DWORD sz; DWORD width; DWORD height; DWORD planes_bit_cnt; unsigned char compression [4]; DWORD image_sz; DWORD xpels_meter; DWORD ypels_meter; DWORD num_colors; // used colors DWORD imp_colors; // important colors / * may be more For Some Codecs * / Avi_Strf () {} AVI_STRF (DWORD S, DWORD W, DWORD H, DWORD P, CHAR Const * C, DWORD I, DWORD X, DWORD Y, DWORD N, DWORD IMP): SZ (s), Width (W), Height (h), planes_bit_cnt (p), image_sz (i), xpels_meter (x), ypels_meter (y), num_colors (n), IMP_COLORS (IMP) {for (INT i = 0; i <4 i) compression [i] = c [i];} avi_strf (avi_strf const & strf) {sz = strf.sz; width = strf.width; height = strf.Height; Planes_bit_cnt = strf.planes_bit_cnt; image_sz = strf .image_sz; xpels_meter = strf.xpels_meter; ypels_meter = strf.ypels_meter; num_colors = strf.num_colors; imp_colors = strf.imp_colors; for (int i = 0; i <4; i) compression [i] = strf.compression [i];} ~ avi_strf () {} friend Ostream & Oper Ator << (Ostream & Out, Avi_Strf Const & Strf) {OUT << Strf.sz << OUT << Strf.width << Strf.Height << Strf.Planes_bit_cnt; out << strf.compression [0] << Strf. Compression [1] << strf.compression [2] << strf.compression [3]; out << strf.image_sz << strf.xpels_meter << strf.ypels_meter << strf.num_colors << strf.imp_colors; return out ;}};

/ * AVI_list_hdr spc: a very ubiquitous AVI struct, used in list structures to specify type and length * / struct AVI_list_hdr {unsigned char id [4]; / ​​* "LIST" * / DWORD sz; / * size of owning struct minus 8 * / Unsigned char Type [4]; / ​​* TYPE OF LIST * / AVI_LIST_HDR () {} avi_list_hdr (char const * value) {sz = d; for (int i = 0; i < 4; i) {id [i] = list [i]; type [i] = value [i];}} avi_list_hdr (avi_list_hdr const & hdr) {for (int i = 0; i <4; i ) {ID [i] = hdr.id [i]; type [i] = hdr.type [i];} SZ = HDR.SZ;} ~ avi_list_hdr () {}

Friend Ostream & Operator << (Ostream & Out, Avi_List_HDR Const & HDR) {OUT << Hdr.id [0] << HDr.ID [1] << HDr.ID [3] << HDr.ID [4] << HDR .sz << HDr.Type [0] << Hdr.Type [1] << HDr.Type [2] << HDr.Type [3]; Return Out;}};

Struct avi_list_odml {structure avi_list_hdr list_hdr;

UNSIGNED Char ID [4]; DWORD SZ; DWORD FRAMES;

AVI_LIST_ODML () {} avi_list_odml (Char Const * L1, DWORD D1, CHAR Const * V1, CHAR Const * L2, DWORD D2, DWORD F): LIST_HDR (L1, D1, V1), SZ (D2), FRAMES (F) {For (int i = 0; i <4; i) ID [i] = l2 [i];} avi_list_odml (avi_list_hdr const HDR, CHAR Const * V, DWORD D2, DWORD F): List_HDR (HDR), SZ (D2), FRAMES (F) {for (INT i = 0; i <4; i) ID [i] = v [i];} avi_list_odml (avi_list_odml const & odml): list_hdr (odml.list_hdr), SZ (odml.sz), frames (odml.frames) {for (int i = 0; i <4; i) ID [i] = odml.id [i];} ~ avi_list_odml () {}

Friend Ostream & Operator << (Ostream & Out, Avi_List_odml Const & Odml) {OUT << ODML.List_HDR << Odml.ID [0] << Odml.id [1] << Odml.id [2] << odml.id [ 3]; out << odml.sz << odml.frames; return out;}}; struct AVI_list_strl {struct AVI_list_hdr list_hdr; / * chunk strh * / unsigned char strh_id [4]; DWORD strh_sz; struct AVI_strh strh; / * Chunk strf * / unsigned char strf_id [4]; dword strf_sz; struct avi_strf strf; / * list odml * / struct avi_list_odml list_odml;};

struct AVI_list_hdrl {struct AVI_list_hdr list_hdr; / * chunk avih * / unsigned char avih_id [4]; DWORD avih_sz; struct AVI_avih avih; / * list strl * / struct AVI_list_hdr strl_hdr; / * chunk strh * / unsigned char strh_id [4]; DWORD strh_sz; struct AVI_strh strh; / * chunk strf * / unsigned char strf_id [4]; DWORD strf_sz; struct AVI_strf strf; / * list odml * / struct AVI_list_odml list_odml; AVI_list_hdrl (DWORD width = 0, DWORD height = 0, DWORD JPG_SZ = 1, DWORD PER_USEC = 1, DWORD FRAMES = 1): List_HDR ("List", SIZEOF (Struct Avi_List_HDRL) - 8, "HDRL") // * chunk avih * /, avih_sz (SIZEOF (Struct Avi_AVIH)), Avih (Per_usec, 1000000 * (JPG_SZ / FRAMES) / PER_USEC, (0), Avif_Hasindex, Frames, 0, 1, 0, Width, Height) // List strl, strl_hdr ("List", SIZEOF (Struct Avi_List_Strl) - 8 , "Strl") // Chunk strH, strH_sz (SIZEOF (Struct Avi_StrH)), Strh ("VIDS", "MJPG", 0, 0, 0, Per_usec, 1000000, 0, Frames, 0, 0, 0) / / chunk strf, strf_sz (SIZEOF (AVI_STRF)), STRF (SIZEOF (Struct Avi) _STRF), Width, Height, 1 24 * 256 * 256, "MJPG", Width * Height * 3, 0, 0, 0, 0) // List ODML, List_ODML ("List", 16, "ODML", "DMLH", 4, frames) {avih_id [0] = 'a'; avih_id [1] = 'v'; avih_id [2] = 'i'; avih_id [3] = 'h'; strH_id [0] = 's'; strH_id [1] = 'T'; strH_id [2] = 'r'; strH_id [3] = 'h'; strf_id [0] = 's'; strf_id [1] = 't'; strf_id [2] = 'r'; strf_id [3] = 'f';} ~ avi_list_hdrl ()}

Friend Ostream & Operator << (Ostream & Out, Avi_List_HDRL Const & HDRL) {OUT << Hdrl.List_HDR << Hdrl.avih_ID [0] << Hdrl.avih_ID [1] << HDRL.AVIH_ID [2] << HDRL.AVIH_ID [ 3]; OUT << HDRL.AVIH_SZ << HDRL.STRL_HDR; OUT << HDRL.STRH_ID [0] << HDRL.STRH_ID [1] << HDRL.STRH_ID [2] << HDRL.STRH_ID [3]; OUT << hdrl.strh_sz << hdrl.strh; out << HDRL.STRF_ID [0] << hdrl.strf_id [1] << hdrl.strf_id [2] << hdrl.strf_id [3]; OUT << HDRL. STRF_SZ << HDRL.STRF << HDRL.List_odml; return out;}}; # endif //_avi_format_h_//aviGenerator.h#ifndef _avi_generator_h_ # define _AVI_Generator_h_ # define debug_version

#include #include #include #include "aviformat.h"

Using namespace std; / * 4 bytes * / typedf int word; type; / * 1 byte * / typed;

class AviGenerator {public: AviGenerator (void); ~ AviGenerator (void); void set_avi_file (string const & file); void set_fps (int fps); int add_frame (string const & file); void set_avi_size (int w, int h);

INT generate_avi (); private: int file_size; int files_size ();

INT INITALIZE_HEADER ();

Void Print_quarte (file * file, dword i); public: static dword const Max_riff_sz = 2147483648ll; / * max avi file size, 2 gb limited * / static dword const jpeg_data_sz = sizeof (dword) * 2;

Struct JPEG_DATA {DWORD SIZE; DWORD OFFSET; String Name; / * i.e. Variable Length Structure * /

JPEG_DATA ()} ~ jpeg_data ()}

Friend Bool Operator <(JPEG_DATA Const & A, JPEG_DATA Const & O) {Return A.Name <.name;} static bool lestthan (jpeg_data const * a, jpeg_data const * o) {Return A-> Name Name; }}; protected: string avi_name_; WORD fps_; WORD frames_; WORD usec_per_frame; // file structure AVI_list_hdrl list_hdrl; // file list vector jpeg_list; // option DWORD width; DWORD height; DWORD frames; unsigned int fps Long JPG_SZ; SIZE_T JPG_SZ_64; SIZE_T RIFF_SZ_64; DWORD RIFF_SZ;}; # endif // avigeerator.cpp

#include "avigenerator.h" #include #include #include #include #include #ifdef _win32 #include #include #else #include #include #endifusion namespace std;

AviGenerator :: AviGenerator (Void): FPS (15), Frames (1), JPG_SZ (1), Width (320), Height (240) {USEC_PER_FRAME = 1000000 / fps;}

AviGenerator :: ~ avigenerator (void) {for (Vector iter = this-> jpeg_list.begin (); it! = Jpeg_list.end (); iter) {JPEG_DATA * P = * iter Delete p;} this-> jpeg_list.clear ();

Void AviGenerator :: set_avi_file (string constatabase) {this-> avi_name_ = file;}

Void AviGenerator :: set_fps (int FPS) {this-> fps_ = fps; this-> usec_per_frame = 1000000 / fps;}

Void avigenerator :: set_avi_size (int w, int h) {this-> width = W; this-> height = h;}

Int avigenerator :: file_size (string const "{int Ret; #ifdef _win32 struct __stat64 result; if (-1 == _stat64 (file.c_str (), & result)) Return -1; Ret = Result.st_size; #else Struct stat s; if (-1 == st (file.c_str (), & s) Return -1; Ret = s.st_size; # endif # ifdef debug_version cerr << file.c_str () << "Size IS" << RET << End1;} int avigenerator :: files_size () {int RET = 0; int TMP, IT; for (Vector :: Iterator iter = JPEG_List.Begin (); iter ! = JPEG_List.end (); iter) {it = (* iter) -> size; tmp = it! = 0? it: file_size ((* iter) -> name.c_str ()); RET = TMP; RET = (4 - (TMP% 4))% 4;} return ret;

INT aviGenerator :: add_frame (string constatabase) {int size = file_size (file); if (size <= 0) return -1; struct jpeg_data * jpeg = new jpeg_data (); jpeg-> name = file; jpeg-> Size = size; jpeg-> offset = 0; this-> jpeg_list.insert (jpeg_list.begin (), jpeg); return 0;}

Void avigenerator :: print_quarte (file * file, dword i) {for (int J = 0; j <4; j) {FPUTC (I% 0x0100, file); I / = 0x100;}}

Int avigenerator :: initalize_header () {frames = this-> jpeg_list.size (); if (frame <= 0) return -1; / * getting image, and hence, riff size * / jpg_sz_64 = this-> files_size () ; If (-1 == jpg_sz_64) {CERR << "COULDN't DETERMINE SIZE OF IMAGES" << Endl; Return -2;} riff_sz_64 = sizeof (Struct Avi_List_HDRL) 4 4 JPG_SZ_64 8 * frames 8 8 16 * frame;

if (riff_sz_64> = MAX_RIFF_SZ) {cerr << "RIFF would exceed 2 Gb limit" << endl; return -3;} jpg_sz = (long) jpg_sz_64; riff_sz = (DWORD) riff_sz_64; // update the struct AVI_list_hdrl this- > list_hdrl.avih.usec_per_frame = LILEND4 (usec_per_frame); this-> list_hdrl.avih.max_bytes_per_sec = LILEND4 ((int) 1000000 * (jpg_sz / frames) / usec_per_frame); this-> list_hdrl.avih.flags = LILEND4 (AVIF_HASINDEX) This-> list_hdrl.avih.tot_frames = lilend4; this-> list_hdrl.avih.width = lilend4 (width); this-> list_hdrl.avih.Height = Lilend4 (Height); this-> list_hdrl.strh. Scale = lilend4; this-> list_hdrl.strh.rate = lilend4 (10000); this-> list_hdrl.strh.Length = Lilend4; this-> list_hdrl.strf.width = lilend4 (width); this -> list_hdrl.strf.Height = Lilend4 (Height); this-> list_hdrl.strf.image_sz = lilend4 (width * height * 3); this-> list_hdrl.list_odml.frames = lilend4;

Return 0;}

Int aviGenerator :: generate_avi () {if (this-> initalize_header ()! = 0) Return -1;

// Open the file file * fdest = fopen (this-> avi_name_.c_str (), "wb"); if (null == fdest) {CERR << "can't create a new file to write (" << This-> avi_name_ << ")!" << endl; return -2;} // fwrite (& list_hdrl.avih.max_bytes_per_sec, 4, 1, fdest); long NBR; long NBW; long tnbw = 0; long mfsz; Long Remnant; char buff [512];

// Write File HEADER FWRITE ("Riff", 4, 1, FDEST; Print_quartet (FDEST, Riff_SZ); FWRITE ("AVI", 4, 1, FDEST); FWRITE (& List_hdrl, Sizeof (Struct Avi_List_HDRL), 1, FDEST);

// sort the list by file name sort (this-> jpeg_list.begin (), this-> jpeg_list.end (), avigenerator :: jpeg_data :: lestthan); // list movi size_t offset = 4; fwrite ("List) ", 4, 1, fdest); Print_quartet (FDEST, JPG_SZ 8 * frames 4); FWRITE (" Movi ", 4, 1, FDEST); // Write Video Data for (Vector :: Iterator iter = this-> jpeg_list.begin (); it! = JPEG_List.end (); t) {#ifdef debug_version cout << "dealing with" << (* ip) -> name << endl; #endif FWRITE ("00db", 4, 1, fdest); mfsz = (* ip) -> size; remnant = (4 - (mfsz% 4))% 4; print_quartet (fdest, mfsz remnant); (* iter) -> size = remnant; (* iter) -> offset = offset; offset = (* ip) -> size 8; int fd; #ifdef _win32 fd = open ((* ip) -> name.c_str ), O_rdonly | o_binary; #else fd = open ((* iter) -> name.c_str (), o_rdonly); #ENDIF IF (fd <0) {CERR << "COULDN'T OPEN FILE (" << (* iTer) -> name << ")!" << endl; fclose (fdest); return -3;} nbw = 0;

IF ((NBR = Read (FD, BUFF, 6))! = 6) {CERR << "Reading Error" << Endl; Fclose (FDEST); Close (FD); Return-4;} fwrite (buff, NBR) , 1, FDEST; READ (FD, BUFF, 4); FWRITE ("Avi1", 4, 1, FDEST); NBW = 10; While ((NBR = Read (FD, BUFF, 512)> 0) { #ifdef debug_version // cout << "read" << nbr << "Bytes from" << (* iter) -> name << Endl; #ENDIF FWRITE (BUFF, NBR, 1, FDEST); NBW = NBR }

IF (Remnant> 0) {FWRITE (BUFF, REMNANT, 1, FDEST); NBW = Remnant;} TNBW = NBW; Close (fd);}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} (tnbw! = jpg_sz) {CERR << "Error Writing images (Wrote "<< TNBW <<" Bytes, Expected "<< jpg_sz <<" Bytes) "<< endl; fclose (fdest); return -5;} / * indices * / fwrite (" IDX1 ", 4, 1 FDEST; print_quartet (fdest, 16 * frames); for (Vector iTER = this-> jpeg_list.begin (); ore! = jpeg_list.end (); iter) {FWRITE "00db", 4, 1, fdest); Print_quart (FDest, 18); Print_quartet (fdest, (* ip) -> offset; print_quartet (fdest, (* ipear);} // this-> JPEG_List.Clear (); fclose (fdest); Return 0;}

//main.cpp test file // tmp.cpp: Define the entry point of the console application. // # include #include #include "avigenerator.h" Using namespace std;

INT Main (int Argc, char * argv []) {// ofstream fout ("temp.txt", iOS :: out); //fout.close (); avigenenerator generator; for (int i = 1; i < = 38; i) {char C [32]; Sprintf (c, "mao% 02d", i); // joined JPEG files, I have MAO01 ~ 38.jpg file strcat (c, ".jpg") COUT << c << Endl; generator.add_frame (c);} cout << "Generating avi file ... << Endl; if (argc> = 2) generator.set_avi_file (Argv [1] ); Else Generator.set_avi_file ("mao.avi"); generator.set_fps (15); generator.set_avi_size (230, 100); generator.generate_avi ();

// system ("pause"); return 0;} Makefile file is not made, only two.cpp files, there should be no problem with everyone compiled.

The author rewritten the original C code into a class on the original basis, which is easy to use (if you don't like it to find the "original" C code), and join the Win32 platform support (in fact, for the author - The author's program is running under Linux). The author is compiled in VC2003, VC2005 Beta1, and uses G , C is no problem. The generated AVI file is played normally in Media Player, but because there is no compression, it is a bit big (I will consider the improvement ^ _ _ ^), But it is still advantageous than the generation of individual procedures. When you store and transfer, you can use WinRAR to compress (made a free advertising, the compression ratio is great). In addition, it is overloaded <<, useless, because the author is not familiar with the standard library, did not find a way to write a binary, so I returned to the way to call C functions. If you have a way to tell the author? Constantly study ..., welcome Email communication. Darkstar21cn@hotmail.com

转载请注明原文地址:https://www.9cbs.com/read-111786.html

New Post(0)