JPEG轉AVI

//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 __cplusplus
extern "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,LoadFromFile
TMemoryStream,LoadFromStream
TMemoryStream,Write
Memory

Position
Size

 

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

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章