#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
struct RCwindow {
unsigned short int left;
unsigned short int top;
unsigned short int right;
unsigned short int bottom;
};
struct AviChunkHdr {
unsigned char fourcc[4];
unsigned int dataSize;
// ... data
};// Chunk header, dataSize = sizeof(whole structure) - 8
struct AviListHdr {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned char listtype[4];
// ... list
};// List header, dataSize = sizeof(whole structure) - 8
struct AviStrf {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned int strucSize;
unsigned int width;
unsigned int height;
unsigned int bitsCount;
unsigned char compression[4];
unsigned int imgSize;
unsigned int xpelsMeter;
unsigned int ypelsMeter;
unsigned int numColors;
unsigned int impColors;
};// Chunk: avi stream format
struct AviHeader {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned int usFrame;
unsigned int bytesPS;
unsigned int padding;
unsigned int flags;
unsigned int totalFrames;
unsigned int initFrame;
unsigned int streams;
unsigned int bufferSize;
unsigned int width;
unsigned int height;
unsigned int reserved[4];
};// Chunk: avi header
struct AviListStrh {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned char listtype[4];
unsigned char stype[4];
unsigned int flags;
unsigned int priority;
unsigned int start;
unsigned int scale;
unsigned int rate;
unsigned int initFrame;
unsigned int totalFrames;
unsigned int bufferSize;
unsigned int quality;
unsigned int samples;
RCwindow rectangle;
};// List: stream header
struct AviListOdml {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned char listtype[4];
unsigned char stype[4];
unsigned int intSize;
unsigned int jpgFrames;
};// List: openDML
struct AviListStrl {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned char listtype[4];
AviListStrh strh;
AviStrf strf;
AviListOdml list_odml;
};//List: stream list
struct AviListHdrlist {
unsigned char fourcc[4];
unsigned int dataSize;
unsigned char listtype[4];
AviHeader avih;
AviListStrl strl;
};// List: aviheader + streamlist
struct AviRiff {
AviListHdr riffhdr;
AviListHdrlist headerList;
AviListHdr movieList;
};// Lists: RIFF avi Tag + headerList + movieList
struct Jpeg {
unsigned short int soi;
unsigned short int app0;
unsigned short int hlen;
char id[5];
};
int main(int argc, char **argv) {
unsigned int width = 0;
unsigned int height = 0;
sscanf(argv[argc - 1], "%ux%u", &width, &height);
unsigned short jpgFrames = argc - 1;
if (width > 1 && height > 1) jpgFrames --;
else { // default size
width = 800;
height = 600;
}
if(jpgFrames == 0) {
printf("usage:\n\t%s %s\n", argv[0], "1.jpg [...] [widthxheight]");
exit(1);
}
unsigned int aviSize = 0;// max 2^32 = 4G
int bufferSize = 1024;
char buffer[bufferSize + 1];
char aviName[] = "test.avi";
FILE *avi = fopen(aviName, "wb");
if(avi == nullptr) {
printf("create avi file fail!\n");
exit(1);
}
int fps = 1;// frame per second
unsigned int usScale = 1e6;
unsigned int sFrame = usScale/fps;
AviListOdml odml = {
{'L', 'I', 'S', 'T'}, sizeof(AviListOdml) - 8,
{'o', 'd', 'm', 'l'}, {'d', 'm', 'l', 'h'},
sizeof(unsigned int), jpgFrames
};// open dml extention
AviStrf strf = {
{'s', 't', 'r', 'f'}, sizeof(AviStrf) - 8,
sizeof(AviStrf),
width, height, 1 + (24 << 16),
{'M', 'J', 'P', 'G'},
width * height * 3,
0, 0, 0, 0
};// stream format, video
AviListStrh strh = {
{'s', 't', 'r', 'h'}, sizeof(AviListStrh) - 8,
{'v', 'i', 'd', 's'}, {'m', 'j', 'p', 'g'},
0, 0, 0,
sFrame, usScale, 0, jpgFrames,
0, 0, 0,
{0, 0, (unsigned short int)width, (unsigned short int)height}
};// stream header
AviListStrl streamlist = {
{'L', 'I', 'S', 'T'}, sizeof(AviListStrl) - 8,
{'s', 't', 'r', 'l'}, strh, strf, odml
};// stream list
AviHeader avih = {
{'a', 'v', 'i', 'h'}, sizeof(AviHeader) - 8,
sFrame, fps * aviSize/jpgFrames, 0, 0, jpgFrames,
0, 1, 0, width, height, {0}
};// avi header without index
AviRiff riff = {
{// AviListHdr
{'R', 'I', 'F', 'F'}, 0,
{'A', 'V', 'I', ' '}
},
{// AviListHdrlist
{'L', 'I', 'S', 'T'}, sizeof(AviListHdrlist) - 8,
{'h', 'd', 'r', 'l'}, avih, streamlist
},
{ // AviListHdr
{'L', 'I', 'S', 'T'}, 0,
{'m', 'o', 'v', 'i'}
}
};
auto fwritei = [](unsigned int i, FILE *f){
for(int j = 0; j < 4 ; j ++) {
fputc(i & 0xff, f);// LSB first out
i >>= 8;
}
};
long totalBytes = 0;
fseek(avi, sizeof(riff), SEEK_SET);
for(int k = 0; k < jpgFrames; k ++) {
int index = k + 1;
FILE *jpgFile= fopen(argv[index], "rb");
if (jpgFile == nullptr) continue;
long flen = fread(buffer, 1, 11, jpgFile);
buffer[flen] = 0;
auto &jpeg = * (Jpeg *)buffer;
if (flen == 11 && jpeg.soi == 0xd8ff && jpeg.app0 == 0xe0ff &&
strcmp(jpeg.id,"JFIF") == 0) {
fseek(jpgFile, 0L, SEEK_END);
flen = ftell(jpgFile);
printf("%04d. %-12s %-12ld bytes\n", index, argv[index], flen);
fwrite("00dc", 4, 1, avi);
fwritei(flen, avi);
fwrite(buffer, 6, 1, avi);
fwrite("AVI1", 5, 1, avi);
fseek(jpgFile, 11L, SEEK_SET);
int n = 0;
do {
n = fread(buffer, 1, bufferSize, jpgFile);
if(n > 0) fwrite(buffer, n, 1, avi);
} while(n == bufferSize);
totalBytes += flen;
if(flen % 2) {
flen ++;
fputc(0, avi);
}
aviSize += flen + 8;
}
fclose(jpgFile);
}
riff.movieList.dataSize = 4 + aviSize;
riff.riffhdr.dataSize = riff.movieList.dataSize + sizeof(AviRiff) - 8;
riff.headerList.avih.bytesPS = fps * totalBytes / jpgFrames;
fseek(avi, 0l, SEEK_SET);
fwrite(&riff, sizeof(riff), 1, avi);
printf("\nmovieSize=%d, riffSize=%d, maxBytesPS=%d\n",
riff.movieList.dataSize,
riff.riffhdr.dataSize,
riff.headerList.avih.bytesPS
);
printf("%s %ld/(%d bytes) includes %u frames(%u*%u):\n\n",
aviName,
sizeof(riff),
4 + riff.riffhdr.dataSize,
jpgFrames,
width,
height
);
fclose(avi);
}
2020年10月1日 星期四
用 c++ 將 jpeg 檔封裝成 avi 格式檔
訂閱:
文章 (Atom)
Linux mint 玩 waydroid 一些心得
1. 目前使用 linux mint 22.1 作業系統可以順利跑起來, 可上官網去下載, 並安裝到硬碟. 2. 安裝 waydroid 可上網站 https://docs.waydro.id 參考看看: https://docs.waydro.id/usage/inst...
-
1. 上 Firebase 網站 註冊啟用 Firebase : https://firebase.google.com/ 2. 進入 Firebase Console 註冊開啟新專案 : https://console.firebase.google.com/...
-
Flutter 讓人很容易短時間就能開發出 app, 關鍵在於他開發了很多種小部件稱為 Widget, 將Widget 組合起來就是一個 app. 所謂 部 件(Widget)就是一個可以呈現在螢幕上的視覺系 物 件,幾乎可以說 Flutter 每個物件都是 部 件. 開發者透...