JPEG转AVI

    技术2022-05-11  20

    //avi.c

    #include "stdafx.h"#include "avi.h"

    #include <string.h>#include <stdio.h>#include <stdlib.h>

    // header flags

    const u32 AVIF_HASINDEX = 0x00000010;    /* index at end of file */const u32 AVIF_MUSTUSEINDEX=0x00000020;const u32 AVIF_ISINTERLEAVED=0x00000100;const u32 AVIF_TRUSTCKTYPE=0x00000800;const u32 AVIF_WASCAPTUREFILE=0x00010000;const u32 AVIF_COPYRIGHTED=0x00020000;

    int nframes;int totalsize;unsigned int* sizes;

    void bzero(void *s, int n){ memset(s,0,n);}

    void fprint_quartet(/*int fd*/FILE * fp, unsigned int i){    char data[4]; int rt = 0;

        data[0] = (char) i%0x100;    i /= 0x100;    data[1] = (char) i%0x100;    i /= 0x100;    data[2] = (char) i%0x100;    i /= 0x100;    data[3] = (char) i%0x100;

        /*write( fd, &data, 4 );*/ rt = fwrite(&data, 4, 1, fp); if(rt != 1)  printf(" fprintf_quartet failed!  /n ");}

    // start writing an AVI file

     void __stdcall avi_start(/*int fd*/FILE * fp, int frames){    int ofs = sizeof(struct riff_head)+              sizeof(struct list_head)+              sizeof(struct avi_head)+              sizeof(struct list_head)+              sizeof(struct stream_head)+              sizeof(struct frame_head)+              sizeof(struct list_head)+              sizeof(struct dmlh_head)+              sizeof(struct list_head);

        printf( "avi_start: frames = %d/n", frames ); printf( "avi_start: ofs = %d/n", ofs );

       /* lseek(fd, ofs, SEEK_SET);*/ fseek(fp,ofs, SEEK_SET);

        nframes = 0;    totalsize = 0;

        sizes = (unsigned int*) calloc( sizeof(unsigned int), frames );   // hold size of each frame}

    // add a jpeg frame to an AVI file void __stdcall avi_add(/*int fd*/FILE * fp, u8 *buf, int size){    struct db_head db = {"00db", 0};

        printf( "avi_add: nframes = %d, totalsize = %d, size = %d/n", nframes, totalsize, size );

        // overwrite JFIF type with AVI1 /*buf[6]='A';    buf[7]='V';    buf[8]='I'; buf[9]='1';*/

        //while( size%4 )  // size++; // align 0 modulo 4*/    db.size = size;

        /*write( fd, &db, sizeof(db) );*/    fwrite( &db, sizeof(db),1, fp);

        /*write( fd, buf, size );*/ fwrite( buf, size,1, fp);

        sizes[nframes] = size;

        nframes++;    totalsize += size;  // total frame size}

    // finish writing the AVI file - filling in the header  void __stdcall avi_end(/*int fd*/FILE * fp, int width, int height, int fps){    struct idx1_head idx = {"idx1", 16*nframes };    struct db_head db = {"00db", 0};    struct riff_head rh = { "RIFF", 0, "AVI "};    struct list_head lh1 = {"LIST", 0, "hdrl"};    struct avi_head ah;    struct list_head lh2 = {"LIST", 0, "strl"};    struct stream_head sh;    struct frame_head fh;    struct list_head lh3 = {"LIST", 0, "odml" };    struct dmlh_head dh = {"dmlh", 4, nframes };    struct list_head lh4 = {"LIST", 0, "movi"};    int i;    unsigned int offset = 4;

        printf( "avi_end: nframes = %d, fps = %d/n", nframes, fps );

        // write index

        /*write(fd, &idx, sizeof(idx));*/ fwrite(&idx, sizeof(idx), 1, fp);

        for ( i = 0; i < nframes; i++ )    {        //write(fd, &db, 4 ); // only need the 00db  fwrite(&db, 4, 1, fp);        fprint_quartet( fp/*fd*/, 18 );       // ???        fprint_quartet( fp/*fd*/, offset );        fprint_quartet( fp/*fd*/, sizes[i] );        offset += sizes[i] + 8; //+8 (for the additional header)    }

        free( sizes );

        bzero( &ah, sizeof(ah) );    strcpy(ah.avih, "avih");    ah.time = 1000000 / fps;    ah.maxbytespersec = 1000000.0*(totalsize/nframes)/ah.time;    ah.nframes = nframes;    ah.numstreams = 1;    ah.flags = AVIF_HASINDEX;    ah.width = width;    ah.height = height;

        bzero(&sh, sizeof(sh));    strcpy(sh.strh, "strh");    strcpy(sh.vids, "vids");    strcpy(sh.codec, "MJPG");    sh.scale = ah.time;    sh.rate = 1000000;    sh.length = nframes;

        bzero(&fh, sizeof(fh));    strcpy(fh.strf, "strf");    fh.width = width;    fh.height = height;    fh.planes = 1;    fh.bitcount = 24;    strcpy(fh.codec,"MJPG");    fh.unpackedsize = 3*width*height;

        rh.size = sizeof(lh1)+sizeof(ah)+sizeof(lh2)+sizeof(sh)+        sizeof(fh)+sizeof(lh3)+sizeof(dh)+sizeof(lh4)+        nframes*sizeof(struct db_head)+        totalsize + sizeof(struct idx1_head)+ (16*nframes) +4; // FIXME:16 bytes per nframe // the '4' - what for???

        lh1.size = 4+sizeof(ah)+sizeof(lh2)+sizeof(sh)+sizeof(fh)+sizeof(lh3)+sizeof(dh);    ah.size = sizeof(ah)-8;    lh2.size = 4+sizeof(sh)+sizeof(fh)+sizeof(lh3)+sizeof(dh);     //4+sizeof(sh)+sizeof(fh);    sh.size = sizeof(sh)-8;    fh.size = sizeof(fh)-8;    fh.size2 = fh.size;    lh3.size = 4+sizeof(dh);    lh4.size = 4+ nframes*sizeof(struct db_head)+ totalsize;

        /*lseek(fd, 0, SEEK_SET);*/    fseek(fp,0, SEEK_SET);

      /*  write(fd, &rh, sizeof(rh));*/    fwrite( &rh, sizeof(rh), 1, fp);   /* write(fd, &lh1, sizeof(lh1));*/ fwrite( &lh1, sizeof(lh1), 1, fp);    /*write(fd, &ah, sizeof(ah));*/    fwrite( &ah, sizeof(ah), 1, fp);   /* write(fd, &lh2, sizeof(lh2));*/    fwrite( &lh2, sizeof(lh2), 1, fp);    /*write(fd, &sh, sizeof(sh));*/    fwrite( &sh, sizeof(sh), 1, fp);    /*write(fd, &fh, sizeof(fh));*/    fwrite( &fh, sizeof(fh), 1, fp);   /* write(fd, &lh3, sizeof(lh3));*/    fwrite(&lh3, sizeof(lh3), 1, fp);   /* write(fd, &dh, sizeof(dh));*/    fwrite(&dh, sizeof(dh), 1, fp);   /* write(fd, &lh4, sizeof(lh4));*/   fwrite(&lh4, sizeof(lh4), 1, fp);}//avi.h

    #ifndef AVI_H#define AVI_H

    //#include <unistd.h>

    #include <string.h>#include <stdio.h>#include <sys/types.h>

    #ifdef __cplusplusextern "C" {#endif

    void bzero(void *s, int n);

    typedef unsigned char u8;typedef unsigned short u16;typedef unsigned u32;

     

    // function prototypes

     __declspec(dllexport) void __stdcall avi_start(/*int fd*/FILE * fp, int frame); __declspec(dllexport) void __stdcall avi_add(/*int fd*/FILE * fp, u8 *buf, int size); __declspec(dllexport) void __stdcall avi_end(/*int fd*/FILE * fp, int width, int height, int fps);void fprint_quartet(/*int fd*/FILE * fp, unsigned int i);

    // the following structures are ordered as they appear in a typical AVI

    struct riff_head {    char riff[4];               // chunk type = "RIFF"    u32 size;                   // chunk size    char avistr[4];             // avi magic = "AVI "};

    // the avih chunk contains a number of list chunks

    struct avi_head {    char avih[4];               // chunk type = "avih"    u32 size;                   // chunk size    u32 time;                   // microsec per frame == 1e6 / fps    u32 maxbytespersec;         // = 1e6*(total size/frames)/per_usec)    u32 pad;                    // pad = 0    u32 flags;                  // e.g. AVIF_HASINDEX    u32 nframes;                // total number of frames    u32 initialframes;          // = 0    u32 numstreams;             // = 1 for now (later = 2 because of audio)    u32 suggested_bufsize;      // = 0 (no suggestion)    u32 width;                  // width    u32 height;                 // height    u32 reserved[4];            // reserved for future use = 0};

    // the LIST chunk contains a number (==#numstreams) of stream chunks

    struct list_head {    char list[4];               // chunk type = "LIST"    u32 size;    char type[4];};

    struct dmlh_head {    char dmlh[4];               // chunk type dmlh    u32 size;                   // 4    u32 nframes;                // number of frames};

    struct stream_head {    char strh[4];               // chunk type = "strh"    u32 size;                   // chunk size    char vids[4];               // stream type = "vids"    char codec[4];              // codec name (for us, = "MJPG")    u32 flags;                  // contains AVIT_F* flags    u16 priority;               // = 0    u16 language;               // = 0    u32 initialframes;          // = 0    u32 scale;                  // = usec per frame    u32 rate;                   // 1e6    u32 start;                  // = 0    u32 length;                 // number of frames    u32 suggested_bufsize;      // = 0    u32 quality;                // = 0 ?    u32 samplesize;             // = 0 ?};

    struct db_head {    char db[4];                 // "00db"    u32 size;};

    // a frame chunk contains one JPEG image

    struct frame_head {    char strf[4];               // chunk type = "strf"    u32 size;                   // sizeof chunk (big endian)    ?    u32 size2;                  // sizeof chunk (little endian) ?    u32 width;    u32 height;    u16 planes;                 // 1 bitplane    u16 bitcount;               // 24 bpl    char codec[4];              // MJPG (for us)    u32 unpackedsize;           // = 3*w*h    u32 r1;                     // reserved    u32 r2;                     // reserved    u32 clr_used;               // reserved    u32 clr_important;          // reserved};

    struct idx1_head {    char idx1[4];               // chunk type = "idx1"    u32 size;                   // chunk size};

    #ifdef __cplusplus}#endif

    #endif

     

    //delphi中

    unit Avi;

    interface

    uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls, jpeg;

    procedure avi_start(fp : TFileStream; frame : Integer); stdcall;external 'avidll.dll' ;procedure avi_add(fp : TFileStream; buf : PByte; size : Integer); stdcall;external 'avidll.dll' ;procedure avi_end(fp : TFileStream; width, height, fps : Integer); stdcall;external 'avidll.dll' ;

    type  db_head = record    db : array [0..3] of char;                 // "00db"    size : Word;  end;

    type  TForm1 = class(TForm)    Button1: TButton;    Button2: TButton;    procedure Button1Click(Sender: TObject);    procedure Button2Click(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end;

    var  Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);var  fp2, PicFile : TFileStream;  PData1, PData2 : ^Byte;  Size1 : Integer;  Sr : TSearchRec;  FileName, PicPath : String;  //buf: array[0..100-1] of Byte;  //I : Integer;  db : db_head;begin  try      FileName := 'F:/avi/AviDemo/test.avi';      //fp2 := nil;      fp2 := TFileStream.Create(FileName,fmOpenWrite);

          {for I := 0 to 99 do      begin          buf[I] := I + 1;      end;}      try        fp2.Seek(240,soFromBeginning);        {fp2.Write(buf,99);        Exit;}      except      end;      //tempstream.Create('');      {try          avi_start(fp2, 300);      except          on E:Exception do          begin              ShowMessage('初始化时发生错误,原因:' + E.Message);              Exit;          end;      end; }      Size1 := 0;      PicPath := 'E:/Console/AlarmControlClient/13Dev/20090824/8HH/40NN/';      if FindFirst(PicPath + '*.jpg',0,Sr) = 0 then      begin          repeat              if ExtractFileExt(Sr.Name) = '.jpg' then              begin                  Size1 := Sr.Size;                  PicFile := TFileStream.Create(PicPath + Sr.Name,fmOpenRead);                  PicFile.Read(PData1,Size1);                  StrPCopy(db.db,'00db');                  db.size := Size1;                  fp2.Write(db,SizeOf(db));                  fp2.Write(PData1,Size1);                   //fwrite( &db, sizeof(db),1, fp);fwrite( buf, size,1, fp);

                      //avi_add(fp2,PData1,Size1);              end;          until FindNext(Sr) <> 0;          FindClose(Sr);      end;      //avi_end(fp2,352,288,12);  finally      //MYJpeg.Free;      fp2.Free;  end;end;

    procedure TForm1.Button2Click(Sender: TObject);var  FileName : string;  FHandle : Integer;begin  FileName := 'Test.avi';  if(not fileExists(FileName))then  begin      FHandle := FileCreate(FileName);      FileClose(FHandle);      ShowMessage('创建成功');  end;end;

    end.

     

    TMemoryStream.LoadFromFile('')

    Load之后 TStream,有个Memory属性. 是指针类型 它指向数据流的开始处 Size属性是它的大小 var  pData: PByte;  ......  pData := YourStream.Memory; 然后就象一般的内存那样用了,比如内存拷贝:  copyMemory(pDest, pData, YourStream.Size)

    用TMemoryStream,LoadFromFileTMemoryStream,LoadFromStreamTMemoryStream,WriteMemory

    PositionSize

     

    http://blog.csdn.net/happydeer/archive/2004/04/16/8775.aspx

     

    http://www.delphi-jedi.org/apilibrary.html


    最新回复(0)