llist.h文件: #ifndef _LLIST_H_ #define _LLIST_H_ typedef struct _List List; struct _List { void *data; List *next; List *prev; }; List *list_erase (List *l); List *list_erased (List *l); void list_rerase (List *l); void list_rerased (List *l); void list_insert (List *l, void *data); List *list_push_front (List *l, void *data); List *list_push_back (List *l, void *data); void list_pop_front (List *l); void list_pop_back (List *l); void list_popd_front (List *l); void list_popd_back (List *l); List *list_front (List *l); List *list_back (List *l); void list_remove (List *l, void *data); List *list_find (List *l, void *data); List *list_nth (List *l, unsigned int n); unsigned int list_size (List *l); #endif llist.c文件: #include "llist.h" #include <stdlib.h> List *list_erase(List *l) { List *next = l->next; if (l->prev) l->prev->next = next; if (next) l->next->prev = l->prev; free(l); return next; } List *list_erased(List *l) { if (l->data) { free(l->data); l->data = 0; } return list_erase(l); } void list_rerase(List *l) { if (l->next) list_rerase(l->next); l->next = 0; free(l); } void list_rerased(List *l) { if (l->next) list_rerased(l->next); l->next = 0; if (l->data) { free(l->data); l->data = 0; } free(l); } void list_insert(List *l, void *data) { List *next = (List *) malloc(sizeof(List)); next->data = l->data; next->next = l->next; next->prev = l; l->data = data; l->next = next; } List *list_push_front(List *l, void *data) { l = list_front(l); l->prev = (List *) malloc(sizeof(List)); l->prev->data = data; l->prev->next = l; l->prev->prev = 0; return l->prev; } List *list_push_back(List *l, void *data) { l = list_back(l); l->next = (List *) malloc(sizeof(List)); l->next->data = data; l->next->next = 0; l->next->prev = l; return l->next; } void list_pop_front(List *l) { list_erase(list_front(l)); } void list_pop_back(List *l) { list_erase(list_back(l)); } void list_popd_front(List *l) { list_erased(list_front(l)); } void list_popd_back(List *l) { list_erased(list_back(l)); } List *list_front(List *l) { while (l->prev) l = l->prev; return l; } List *list_back(List *l) { while (l->next) l = l->next; return l; } void list_remove(List *l, void *data) { List *l2; while ((l2 = list_find(l, data))) l = list_erase(l2); } List *list_find(List *l, void *data) { while (l && (l->data != data)) l = l->next; return l; } List *list_nth(List *l, unsigned int n) { unsigned int i; for (i = 0; (i < n) && (l); ++i, l = l->next); return l; } unsigned int list_size(List *l) { int i; for (i = 0; (l); ++i, l = l->next); return i; } avifmt.h文件: #ifndef _AVIFMT_H_ #define _AVIFMT_H_ #define SWAP2(x) (((x>>8) & 0x00ff) | ((x<<8) & 0xff00)) #define SWAP4(x) (((x>>24) & 0x000000ff) | ((x>>8) & 0x0000ff00) | ((x<<8) & 0x00ff0000) | ((x<<24) & 0xff000000)) #define LILEND2(a) (a) #define LILEND4(a) (a) #define BIGEND2(a) SWAP2((a)) #define BIGEND4(a) SWAP4((a)) typedef int WORD; typedef unsigned int DWORD; typedef char BYTE; const DWORD AVIF_HASINDEX = 0x00000010; 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 us_per_frame; DWORD max_bytes_per_sec; DWORD padding; DWORD flags; DWORD tot_frames; DWORD init_frames; DWORD streams; DWORD buff_sz; DWORD width; DWORD height; DWORD reserved[4]; }; struct rcFrame { short int left; short int top; short int right; short int bottom; }; struct AVI_strh { unsigned char type[4]; unsigned char handler[4]; DWORD flags; DWORD priority; DWORD init_frames; DWORD scale; DWORD rate; DWORD start; DWORD length; DWORD buff_sz; DWORD quality; DWORD sample_sz; struct rcFrame rc; }; ////////////////////////////////////////////////////////////////////////// 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; DWORD imp_colors; }; struct AVI_list_hdr { unsigned char id[4]; DWORD sz; unsigned char type[4]; }; struct AVI_list_odml { struct AVI_list_hdr list_hdr; unsigned char id[4]; DWORD sz; DWORD frames; }; struct AVI_list_strl { struct AVI_list_hdr list_hdr; unsigned char strh_id[4]; DWORD strh_sz; struct AVI_strh strh; unsigned char strf_id[4]; DWORD strf_sz; struct AVI_strf strf; struct AVI_list_odml list_odml; }; struct AVI_list_hdrl { struct AVI_list_hdr list_hdr; unsigned char avih_id[4]; DWORD avih_sz; struct AVI_avih avih; struct AVI_list_strl strl; }; #endif jpegtoavi.c文件: #define VERSION_MAJ 1 #define VERSION_MIN 0 #include <stdio.h> #include "avifmt.h" #include <string.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <io.h> #include "llist.h" typedef struct _Jpeg_Data Jpeg_Data; typedef unsigned long off64_t; struct _Jpeg_Data { DWORD size; DWORD offset; char name[0]; }; #define JPEG_DATA_SZ (sizeof(DWORD) * 2) #define PATH_MAX 255 off_t file_sz(char *fn) { struct stat s; if (stat(fn, &s) == -1) return -1; return s.st_size; } off_t get_file_sz(List *l) { off_t tmp, ret = 0; for(; (l); l = l->next) { if((tmp = file_sz(((Jpeg_Data *)l->data)->name)) == -1) return -1; ((Jpeg_Data *)l->data)->size = (DWORD) tmp; tmp += ((4-(tmp%4)) % 4); ret += tmp; } return ret; } List *get_file_list_argv(int argc, char **argv) { List *ret = (List *) malloc(sizeof(List)), *l = ret; Jpeg_Data *tmp; int i; ret->data = 0; ret->prev = 0; ret->next = 0; for (i = 0; i < argc; ++i) { tmp = (Jpeg_Data *) malloc(strlen(argv[i]) + 1 + JPEG_DATA_SZ); strcpy(tmp->name,argv[i]); if (l->data == 0) l->data = tmp; else l = list_push_back(l, tmp); } return ret; } void print_quartet(unsigned int i, FILE *out) { putc(i % 0x100, out); i /= 0x100; putc(i % 0x100, out); i /= 0x100; putc(i % 0x100, out); i /= 0x100; putc(i % 0x100, out); } int main() { FILE *out; char tempstr[255]; DWORD per_usec = 1; DWORD width = 1; DWORD height = 1; DWORD frames = 1; unsigned int fps; unsigned short img0; off64_t jpg_sz_64, riff_sz_64; long jpg_sz = 1; const off64_t MAX_RIFF_SZ = 2147483648L; // 2 GB limit DWORD riff_sz; int fd; long nbr, nbw, tnbw = 0; char buff[512]; off_t mfsz, remnant; List *frlst = 0, *f = 0; int i; char* fold ="E://图片//背景图片//"; int imgNum; char** imgName; struct AVI_list_hdrl hdrl = { { {'L', 'I', 'S', 'T'}, LILEND4(sizeof(struct AVI_list_hdrl) - 8), {'h', 'd', 'r', 'l'} }, {'a', 'v', 'i', 'h'}, LILEND4(sizeof(struct AVI_avih)), { LILEND4(per_usec), LILEND4(1000000 * (jpg_sz/frames) / per_usec), LILEND4(0), LILEND4(AVIF_HASINDEX), LILEND4(frames), LILEND4(0), LILEND4(1), LILEND4(0), LILEND4(width), LILEND4(height), {LILEND4(0), LILEND4(0), LILEND4(0), LILEND4(0)} }, { { {'L', 'I', 'S', 'T'}, LILEND4(sizeof(struct AVI_list_strl) - 8), {'s', 't', 'r', 'l'} }, {'s', 't', 'r', 'h'}, LILEND4(sizeof(struct AVI_strh)), { {'v', 'i', 'd', 's'}, {'M', 'J', 'P', 'G'}, LILEND4(0), LILEND4(0), LILEND4(0), LILEND4(per_usec), LILEND4(1000000), LILEND4(0), LILEND4(frames), LILEND4(0), LILEND4(0), LILEND4(0), LILEND2(0), LILEND2(0), LILEND2(160), LILEND2(120) }, {'s', 't', 'r', 'f'}, sizeof(struct AVI_strf), { LILEND4(sizeof(struct AVI_strf)), LILEND4(width), LILEND4(height), LILEND4(1 + (24<<16)), {'M', 'J', 'P', 'G'}, LILEND4(width * height * 3), LILEND4(0), LILEND4(0), LILEND4(0), LILEND4(0) }, { { {'L', 'I', 'S', 'T'}, LILEND4(16), {'o', 'd', 'm', 'l'} }, {'d', 'm', 'l', 'h'}, LILEND4(4), LILEND4(frames) } } };//end of ldrl imgNum = 70 ; imgName = (char**)malloc((imgNum)*sizeof(char*)); for(i=0;i<imgNum;i++){ imgName[i] = (char*)malloc(sizeof(char)*50); sprintf(imgName[i],"%s%03d.jpg",fold,(i+1)); } frlst = get_file_list_argv(imgNum , imgName); frames = list_size(frlst); jpg_sz_64 = get_file_sz(frlst); if (jpg_sz_64 == -1) { fprintf(stderr, "couldn't determine size of images/n"); return -2; } riff_sz_64 = sizeof(struct AVI_list_hdrl) + 4 + 4 + jpg_sz_64 + 8*frames + 8 + 8 + 16*frames; if (riff_sz_64 >= MAX_RIFF_SZ) { fprintf(stderr,"RIFF would exceed 2 GB limit/n"); return -3; } jpg_sz = (long) jpg_sz_64; riff_sz = (DWORD) riff_sz_64; if (img0 == 2) { printf("%lu/n", (unsigned long) riff_sz + 8UL); return 0; } out = fopen("test.avi", "wb"); putc('R', out); putc('I', out); putc('F', out); putc('F', out); print_quartet(riff_sz, out); putc('A', out); putc('V', out); putc('I', out); putc(' ', out); hdrl.avih.us_per_frame = LILEND4(per_usec); hdrl.avih.max_bytes_per_sec = LILEND4(1000000 * (jpg_sz/frames) / per_usec); hdrl.avih.tot_frames = LILEND4(frames); hdrl.avih.width = LILEND4(width); hdrl.avih.height = LILEND4(height); hdrl.strl.strh.scale = LILEND4(per_usec); hdrl.strl.strh.rate = LILEND4(1000000); hdrl.strl.strh.length = LILEND4(frames); hdrl.strl.strf.width = LILEND4(width); hdrl.strl.strf.height = LILEND4(height); hdrl.strl.strf.image_sz = LILEND4(width * height * 3); hdrl.strl.list_odml.frames = LILEND4(frames); fwrite(&hdrl, sizeof(hdrl), 1, out); putc('L', out); putc('I', out); putc('S', out); putc('T', out); print_quartet(jpg_sz + 8*frames + 4, out); putc('m', out); putc('o', out); putc('v', out); putc('i', out); for (f = frlst; (f); f = f->next) { putc('0', out); putc('0', out); putc('d', out); putc('c', out); mfsz = ((Jpeg_Data *) f->data)->size; remnant = (4-(mfsz%4)) % 4; print_quartet(mfsz + remnant, out); ((Jpeg_Data *) f->data)->size += remnant; if (f == frlst) ((Jpeg_Data *) f->data)->offset = 4; else ((Jpeg_Data *) f->data)->offset = ((Jpeg_Data *) f->prev->data)->offset + ((Jpeg_Data *) f->prev->data)->size + 8; strcpy(tempstr, ((Jpeg_Data *) f->data)->name); if ((fd = _open(tempstr, O_RDONLY | O_BINARY)) < 0) { fprintf(stderr, "couldn't open file!/n"); return -6; } nbw = 0; if ((nbr = _read(fd, buff, 6)) != 6) { fprintf(stderr, "error/n"); return -7; } fwrite(buff, nbr, 1, out); _read(fd, buff, 4); fwrite("AVI1", 4, 1, out); nbw = 10; while ((nbr = _read(fd, buff, 512)) > 0) { fwrite(buff, nbr, 1, out); nbw += nbr; } if (remnant > 0) { fwrite(buff, remnant, 1, out); nbw += remnant; } tnbw += nbw; _close(fd); } if (tnbw != jpg_sz) { fprintf(stderr, "error writing images (wrote %ld bytes, expected %ld bytes)/n", tnbw, jpg_sz); return -8; } putc('i', out); putc('d', out); putc('x', out); putc('1', out); print_quartet(16 * frames, out); for (f = frlst; (f); f = f->next) { putc('0', out); putc('0', out); putc('d', out); putc('c', out); print_quartet(18, out); print_quartet(((Jpeg_Data *) f->data)->offset, out); print_quartet(((Jpeg_Data *) f->data)->size, out); } fclose(out); return 0; }