import aml_image_packer
authorJan Altensen <info@stricted.net>
Mon, 21 Jun 2021 21:44:47 +0000 (23:44 +0200)
committerJan Altensen <info@stricted.net>
Mon, 21 Jun 2021 21:44:47 +0000 (23:44 +0200)
 * from https://github.com/khadas/buildroot_buildroot/tree/buildroot/package/aml_image_packer/src

Change-Id: I708523bffc5e3b1152fcf747f48f62c108034efe

15 files changed:
Android.mk [new file with mode: 0644]
Makefile [new file with mode: 0644]
amlImage.cpp [new file with mode: 0644]
amlImage_if.h [new file with mode: 0644]
crc32.cpp [new file with mode: 0644]
crc32.h [new file with mode: 0644]
dll.h [new file with mode: 0644]
image_packer.vcxproj [new file with mode: 0644]
image_packer.vcxproj.filters [new file with mode: 0644]
image_packer.vcxproj.user [new file with mode: 0644]
image_packer_i.h [new file with mode: 0644]
sha1.c [new file with mode: 0644]
sha1.h [new file with mode: 0644]
sparse_format.cpp [new file with mode: 0644]
sparse_format.h [new file with mode: 0644]

diff --git a/Android.mk b/Android.mk
new file mode 100644 (file)
index 0000000..b576b47
--- /dev/null
@@ -0,0 +1,72 @@
+# 
+# Copyright 2013 The Amlogic Iamge Pack Tool
+#
+# image pack tool
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+SRC_FILES := \
+       crc32.c \
+       sha1.c \
+       amlImage.c \
+       sparse_format.c
+
+ifeq ($(strip $(USE_MINGW)),y) 
+#################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_MODULE := libimagepack
+LOCAL_CFLAGS := -DBUILD_LIBRARY -D_LARGEFILE64_SOURCE  -D_FILE_OFFSET_BITS=64 -DBUILD_WITH_MINGW
+ifeq ($(strip $(USE_MINGW)),y)
+LOCAL_CFLAGS += -DBUILD_DLL 
+endif
+
+include $(BUILD_HOST_SHARED_LIBRARY)   
+       
+       
+#################################
+       
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_CFLAGS := -D_LARGEFILE64_SOURCE  -D_FILE_OFFSET_BITS=64 -DBUILD_WITH_MINGW
+LOCAL_MODULE := aml_image_packer
+
+include $(BUILD_HOST_EXECUTABLE)
+
+else
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_STATIC_LIBRARIES := libc
+LOCAL_MODULE := libimagepack
+LOCAL_CFLAGS := -DBUILD_LIBRARY -D_LARGEFILE64_SOURCE  -D_FILE_OFFSET_BITS=64
+
+include $(BUILD_STATIC_LIBRARY)
+#################################
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_SYSTEM_SHARED_LIBRARIES := libc
+LOCAL_MODULE := libimagepack
+LOCAL_CFLAGS := -DBUILD_LIBRARY -D_LARGEFILE64_SOURCE  -D_FILE_OFFSET_BITS=64
+
+include $(BUILD_SHARED_LIBRARY)
+
+       
+#################################
+       
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_MODULE := aml_image_packer
+LOCAL_CFLAGS := -D_LARGEFILE64_SOURCE  -D_FILE_OFFSET_BITS=64
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif
+
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..eb3ac78
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+
+image_packer: crc32.o sha1.o sparse_format.o amlImage.o
+       g++ --static -o aml_image_v2_packer crc32.o sha1.o sparse_format.o amlImage.o
+
+clean:
+       rm crc32.o sha1.o sparse_format.o amlImage.o
+
diff --git a/amlImage.cpp b/amlImage.cpp
new file mode 100644 (file)
index 0000000..7a1b13b
--- /dev/null
@@ -0,0 +1,1066 @@
+/*
+ * \file        amlImage.c
+ * \brief       Amlogic firmware image interface
+ *
+ * \version     1.0.0
+ * \date        2013/5/21
+ * \author      Vinson.Xu <binsheng.xu@amlogic.com>
+ *
+ * Copyright (c) 2013 Amlogic Inc. All Rights Reserved.
+ *
+ */
+#include "image_packer_i.h"
+
+extern "C" {
+int gen_sha1sum_verify(const char* srFile, char* verifyData);
+}
+
+#define COMPILE_TYPE_CHK(expr, t)       typedef char t[(expr) ? 1 : -1]
+
+COMPILE_TYPE_CHK(AML_IMG_ITEM_INFO_SZ == sizeof(ItemInfo), aa);
+COMPILE_TYPE_CHK(AML_IMG_HEAD_INFO_SZ == sizeof(AmlFirmwareImg_t), bb);
+
+#define RW_MAX_SIZE   65536
+#define RW_HEAD_SIZE  8192
+#define ITEM_ALGIN    4
+
+#define debugP(...) //printf("dbg:"),printf(__VA_ARGS__)
+#define errorP(...) printf("ERR:"),printf(__VA_ARGS__)
+
+ImageDecoderIf_t  *ImageDecoder;
+
+static HIMAGE image_open(const char* imagePath)
+{
+       FILE *fp = NULL;
+       fp = fopen(imagePath,"rb");
+       if(fp == NULL){
+               fprintf(stderr,"image open error! [%s]\n",strerror(errno));
+       }
+       return fp;
+}
+
+static int image_check(HIMAGE hImage)
+{
+       FILE* fp = (FILE*)hImage;
+       unsigned int crc32 = 0;
+       
+       if(ImageDecoder->AmlFirmwareImg->crc==0){
+               fseeko(fp,0,SEEK_SET);
+               memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+               if(fread(ImageDecoder->AmlFirmwareImg,sizeof(AmlFirmwareImg_t),1, fp) != 1) {
+                       fprintf(stderr,"cannot read %u bytes  [%s]\n", (unsigned)sizeof(AmlFirmwareImg_t),strerror(errno));
+                       return -1;
+               }
+       }
+
+       if(ImageDecoder->AmlFirmwareImg->magic != IMAGE_MAGIC){
+       fprintf(stderr,"the magic number is not match \n");
+       return -1;
+       }
+
+       crc32 = calc_img_crc(fp, ImageDecoder->AmlFirmwareImg->itemAlginSize);
+       printf("crc32==0x%x\n",crc32);
+       printf("ImageDecoder->AmlFirmwareImg->crc==0x%x\n",ImageDecoder->AmlFirmwareImg->crc);
+       if(crc32!=ImageDecoder->AmlFirmwareImg->crc){
+       fprintf(stderr,"crc check fail !!! \n");
+       return -1;
+       }
+       return 0;
+}
+
+static int image_close(HIMAGE hImage)
+{
+       if(hImage)
+               return fclose((FILE*)hImage);
+       return -1;
+}
+
+static HIMAGEITEM image_open_item(HIMAGE hImage, const char* mainType, const char* subType)
+{
+       FILE* fp = (FILE*)hImage;
+       HIMAGEITEM item = NULL;
+       unsigned int i = 0;
+       if(ImageDecoder->AmlFirmwareImg->crc==0){
+               memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+               fseeko(fp,0,SEEK_SET);
+
+               if(fread(ImageDecoder->AmlFirmwareImg,sizeof(AmlFirmwareImg_t),1,fp)!= 1) {
+                       fprintf(stderr,"Read error[%s] \n", strerror(errno));
+                       return NULL;
+               }
+       }
+
+       if(ImageDecoder->AmlFirmwareImg->magic != IMAGE_MAGIC){
+       fprintf(stderr,"the magic number is not match \n");
+       return NULL;
+       }
+
+       ItemInfo *AmlItem = NULL;
+    AmlItem = (ItemInfo*)malloc(sizeof(ItemInfo)*ImageDecoder->AmlFirmwareImg->itemNum);
+       if(AmlItem == NULL){
+               fprintf(stderr,"malloc %u bytes memmory failed \n", (unsigned)sizeof(ItemInfo));
+               return NULL;
+       }
+
+       fseeko(fp,sizeof(AmlFirmwareImg_t),SEEK_SET);
+       memset(AmlItem,0,sizeof(ItemInfo)*ImageDecoder->AmlFirmwareImg->itemNum);
+       unsigned int read_len = fread(AmlItem,sizeof(ItemInfo), ImageDecoder->AmlFirmwareImg->itemNum,fp);
+
+       if( read_len!= ImageDecoder->AmlFirmwareImg->itemNum) {
+               fprintf(stderr,"cannot read %u bytes  [%s] \n", ImageDecoder->AmlFirmwareImg->itemNum,strerror(errno));
+               return NULL;
+       }       
+       
+       for(;i<ImageDecoder->AmlFirmwareImg->itemNum;i++){
+       
+               if(!strncmp((AmlItem+i)->itemMainType,mainType,32)
+                               &&!strncmp((AmlItem+i)->itemSubType,subType,32)){
+                       item = malloc(sizeof(ItemInfo));
+                       memcpy((void*)item,(void*)(AmlItem+i),sizeof(ItemInfo));
+                       free(AmlItem);
+                       AmlItem = NULL;
+                       break;
+               }       
+       }
+       
+       if(AmlItem){
+               free(AmlItem);
+       }
+       /*
+       do{
+               memset(AmlItem,0,sizeof(ItemInfo));
+               if(fread(AmlItem,1, sizeof(ItemInfo),fp) != sizeof(ItemInfo)) {
+                       fprintf(stderr,"cannot read %ud bytes", sizeof(ItemInfo));
+                       return NULL;
+               }
+
+               if(!strncmp(AmlItem->itemMainType,mainType,32)
+                               &&!strncmp(AmlItem->itemSubType,subType,32)){
+                       item = (HIMAGEITEM)AmlItem;
+                       break;
+               }
+
+               count ++;
+               if(count == ImageDecoder->AmlFirmwareImg->itemNum){
+                       fprintf(stderr,"Item is not found!");
+                       break;
+               }
+       }while(1);
+       */
+
+       return item;
+}
+
+
+static int image_close_item(HIMAGEITEM hItem){
+       if(hItem){
+               free(hItem);
+               hItem = NULL;
+       }
+
+       return 0;
+}
+
+//read item data, like standard fread
+static __u32 image_read_item_data(HIMAGE hImage, HIMAGEITEM hItem, void* buff, const __u32 readSz){
+       if(!hImage||!hItem){
+               fprintf(stderr,"invalid param!");
+       }
+       FILE* fp = (FILE*)hImage;
+       size_t  readlen = 0 ;
+         
+       //static __u32 item_offset = 0;
+       //static __u32 itemId_save = 0;
+       ItemInfo *item = (ItemInfo*)hItem;
+
+       //if(itemId_save!=item->itemId){
+       //      item_offset = 0;
+       //}
+
+       if(item->curoffsetInItem >= item->itemSz){
+               //item_offset = 0;
+               //itemId_save = item->itemId;
+               return 0;
+       }
+
+       fseeko(fp,item->offsetInImage+item->curoffsetInItem,SEEK_SET);
+       if(readSz+item->curoffsetInItem >= item->itemSz){
+               readlen = item->itemSz-item->curoffsetInItem;
+       }else{
+               readlen = readSz;
+       }
+       if(fread(buff,readlen,1,fp)!=1){
+               fprintf(stderr,"read item error! [%s] \n",strerror(errno));
+               return 0;
+       }
+       item->curoffsetInItem += readlen;
+       //itemId_save = item->itemId;
+       return readlen;
+}
+
+//relocate the read pointer to read the item data, like standard fseeko
+static int image_seek_item(HIMAGE hImage, HIMAGEITEM hItem, __s64 offset, __u32 fromwhere)
+{
+       if(!hImage||!hItem){
+               fprintf(stderr,"invalid param!");
+       }
+       int ret = 0;
+       FILE* fp = (FILE*)hImage;
+       ItemInfo *item = (ItemInfo*)hItem;
+       fseeko(fp,item->offsetInImage,SEEK_SET);
+       switch(fromwhere){
+       case SEEK_SET:
+               ret = fseeko(fp,offset,SEEK_CUR);
+               item->curoffsetInItem = offset;
+               break;
+       case SEEK_CUR:
+               ret = fseeko(fp,item->curoffsetInItem+offset,SEEK_CUR);
+               item->curoffsetInItem += offset;
+               break;
+       case SEEK_END:
+               ret = fseeko(fp,item->itemSz+offset,SEEK_CUR);
+               item->curoffsetInItem = item->itemSz+offset;
+               break;
+       default:
+               fprintf(stderr,"invalid param for fromwhere!");
+               ret = -1;
+               break;
+       }
+
+       return ret;
+}
+
+static __u64 image_get_item_size(HIMAGEITEM hItem)
+{
+       if(!hItem){
+               fprintf(stderr,"invalid param!");
+        return 0;
+       }
+
+       ItemInfo *item = (ItemInfo*)hItem;
+       return item->itemSz;
+}
+
+//is the item source is duplicated with other item
+//i.e, item data is empty
+//return value: 0/1 is ok, <0 is failed
+static int is_item_backup_for_other_item(HIMAGEITEM hItem, int* backItemId)
+{
+       ItemInfo *item = (ItemInfo*)hItem;
+    if(!hItem){
+        errorP("NULL item handle\n");
+        return -1;
+    }
+    *backItemId = item->backUpItemId;
+    return item->isBackUpItem;
+}
+
+static int image_get_item_type(HIMAGEITEM hItem)
+{
+       if(!hItem){
+               fprintf(stderr,"invalid param!");
+       }
+
+       ItemInfo *item = (ItemInfo*)hItem;
+       return item->fileType;
+}
+
+
+static int image_get_item_count(HIMAGE hImage,const char* mainType)
+{
+       int count = 0;
+       unsigned int total = 0;
+       FILE* fp = (FILE*)hImage;
+       if(ImageDecoder->AmlFirmwareImg->crc==0){
+               memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+               fseeko(fp,0,SEEK_SET);
+               if(fread(ImageDecoder->AmlFirmwareImg,sizeof(AmlFirmwareImg_t),1, fp) != 1) {
+                       fprintf(stderr,"image_get_item_count : Read Err [%s] \n", strerror(errno));
+                       return -1;
+               }
+       }
+
+       if(mainType == NULL){
+               return ImageDecoder->AmlFirmwareImg->itemNum;
+       }
+
+       ItemInfo *AmlItem = NULL;
+       AmlItem = (ItemInfo*)malloc(sizeof(ItemInfo));
+       if(AmlItem == NULL){
+               fprintf(stderr,"not enough memory \n");
+               return -1;
+       }
+       fseeko(fp,sizeof(AmlFirmwareImg_t),SEEK_SET);
+       do{
+               memset(AmlItem,0,sizeof(ItemInfo));
+               if(fread(AmlItem,1, sizeof(ItemInfo),fp) != sizeof(ItemInfo)) {
+                       fprintf(stderr,"cannot read %u bytes", (unsigned)sizeof(ItemInfo));
+                       return -1;
+               }
+
+               if(!strncmp(AmlItem->itemMainType,mainType,strlen(mainType))){
+                       count ++;
+               }
+
+               //fseeko(fp,AmlItem->itemSz,SEEK_CUR);
+               total ++;
+               if(total == ImageDecoder->AmlFirmwareImg->itemNum){
+                       break;
+               }
+       }while(1);
+
+       free(AmlItem);
+       return count;
+}
+
+static int image_get_next_item(HIMAGE hImage,unsigned int iItem, char* maintype, char* subtype)
+{
+       FILE* fp = (FILE*)hImage;
+       unsigned int nItem = 0;
+       if(ImageDecoder->AmlFirmwareImg->crc==0){
+               memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+               fseeko(fp,0,SEEK_SET);
+               if(fread(ImageDecoder->AmlFirmwareImg,1, sizeof(AmlFirmwareImg_t),fp) != sizeof(AmlFirmwareImg_t)) {
+                       fprintf(stderr,"cannot read %u bytes", (unsigned)sizeof(AmlFirmwareImg_t));
+                       return -1;
+               }
+       }
+
+       if(iItem >= ImageDecoder->AmlFirmwareImg->itemNum){
+        errorP("Item index %u > max %u\n", iItem, ImageDecoder->AmlFirmwareImg->itemNum - 1);
+               return -1;
+    }
+               
+       fseeko(fp,sizeof(AmlFirmwareImg_t)+iItem*sizeof(ItemInfo),SEEK_SET);    
+       
+       ItemInfo AmlItem;
+       memset(&AmlItem,0,sizeof(ItemInfo));
+       if(fread(&AmlItem,sizeof(ItemInfo), 1,fp) != 1) {
+               fprintf(stderr,"image_get_next_item:Read Err [%s]", strerror(errno));
+               return -1;
+       }
+
+       strncpy(maintype,AmlItem.itemMainType,32);
+       strncpy(subtype,AmlItem.itemSubType,32);
+    /*debugP("[%s, %s] verify = %d\n", maintype, subtype, AmlItem.verify);*/
+       return 0;
+}
+
+//#define TAG_WORKDIR     "work_dir"
+//#define TAG_ARCHIVE     "archive_file"
+#define TAG_NORMALLIST  "[LIST_NORMAL]"
+#define TAG_VERIFYLIST  "[LIST_VERIFY]"
+
+#define TAG_LINE    "\r\n"
+#define TAG_LINE_1  "\n"
+
+#define FILE_TAG        "file="
+#define MTYPE_TAG       "main_type="
+#define STYPE_TAG       "sub_type="
+
+static int  image_cfg_parse(char *data,int length)
+{
+       int ret = 0;
+
+       char *key_normal, *key_verify;
+       char *proc , *proc_end;
+       FileList *list = NULL ;
+       int verify = 0;
+
+       key_normal = strstr(data,TAG_NORMALLIST);
+       if(key_normal==NULL){
+               printf("image.cfg parse err: miss [LIST_NORMAL] node \n");
+       }
+
+       key_verify = strstr(data,TAG_VERIFYLIST);
+       if(key_verify==NULL){
+               printf("image.cfg parse: no [LIST_VERIFY] node \n");
+       }
+
+       if(!key_normal&&!key_verify){
+               return -1;
+       }
+       const char* tag_line = TAG_LINE;
+       char* token = strtok(data, TAG_LINE);
+       if(token==NULL){
+               token = strtok(data, TAG_LINE_1);
+               tag_line = TAG_LINE_1;
+       }
+       for( ;token != NULL; token = strtok(NULL,tag_line))
+       {
+               if(*token == '#'){
+                       debugP("skip line: %s \n",token);
+                       continue;
+               }
+               proc = strstr(token,FILE_TAG);
+               if(proc == NULL){
+                       continue;
+               }
+
+               if(key_verify > key_normal){
+                       if(proc > key_normal && proc < key_verify){
+                               verify = 0;
+                       }else if(proc > key_verify ){
+                               verify = 1;
+                               ImageDecoder->gItemCount ++;
+                       }else{
+                               printf("invalid list\n");
+                               continue;
+                       }
+               }else{
+                       if(proc > key_normal ){
+                               verify = 0;
+                       }else if(proc > key_verify && proc < key_normal){
+                               verify = 1;
+                               ImageDecoder->gItemCount ++;
+                       }else{
+                               printf("invalid list\n");
+                               continue;
+                       }
+               }
+               if(list == NULL){
+                       list = (FileList*)malloc(sizeof(FileList));
+                       ImageDecoder->gImageCfg.file_list = list;
+
+               }else{
+                       list->next = (FileList*)malloc(sizeof(FileList));
+                       list = list->next;
+               }
+
+               memset(list,0,sizeof(FileList));
+               list->verify = verify;
+
+               proc = strchr(proc+strlen(FILE_TAG),'\"');
+               proc_end = strchr(proc+1,'\"');
+               strncpy(list->name,proc+1,proc_end-proc-1);
+               //printf("file: %s  ",list->name);
+
+               proc = strstr(token,MTYPE_TAG);
+               if(proc == NULL){
+                       continue;
+               }
+
+               proc = strchr(proc+strlen(MTYPE_TAG),'\"');
+               proc_end = strchr(proc+1,'\"');
+               strncpy(list->main_type,proc+1,proc_end-proc-1);
+               //printf("main_type: %s ",list->main_type);
+
+               proc = strstr(token,STYPE_TAG);
+               if(proc == NULL){
+                       continue;
+               }
+
+               proc = strchr(proc+strlen(STYPE_TAG),'\"');
+               proc_end = strchr(proc+1,'\"');
+               strncpy(list->sub_type,proc+1,proc_end-proc-1);
+               debugP("sub_type: %s \n",list->sub_type);
+               ImageDecoder->gItemCount ++;
+       }
+
+       list = ImageDecoder->gImageCfg.file_list;
+       FileList *plist = ImageDecoder->gImageCfg.file_list;
+       while(ret==0&&list){
+               for(plist = ImageDecoder->gImageCfg.file_list;plist;plist=plist->next){
+
+                       if(plist!=list&&(!strcmp(list->main_type,plist->main_type))&&(!strcmp(list->sub_type,plist->sub_type))){
+                               fprintf(stderr,"Error: config file is illegal! \nmain_type:[%s] sub_type:[%s] is reduplicate \n",list->main_type,list->sub_type);
+                               ret = -1;
+                               break;
+                       }
+               }
+               list = list->next;
+       }
+       if(ret < 0){
+               list = ImageDecoder->gImageCfg.file_list;
+               while(list){
+                       plist = list->next;
+                       free(list);
+                       list = plist;
+               }
+       }
+       return ret;
+}
+
+static int image_check_files(const char* src_dir)
+{
+       char path[256]={0};
+       FileList *list = ImageDecoder->gImageCfg.file_list;
+       do{
+               memset(path,0,256);
+               strcpy(path,src_dir);
+               strcat(path,list->name);
+               debugP("path: %s\n", path);
+               //if(access(path,F_OK|R_OK) < 0){
+               if(access(path, 0) < 0){
+                       printf("Err:%s is not found! \n",path);
+                       return -1;
+               }
+               list = list->next;
+       }while(list!=NULL);
+
+       return 0;
+}
+
+//return the item id, >= 0 if OK
+/*
+ * duplicated item like this, which source is the same file 'boot.PARTITION' but sub_type.main_type are different
+ *file="boot.PARTITION"                main_type="PARTITION"           sub_type="boot"
+ *file="boot.PARTITION"                main_type="PARTITION"           sub_type="bootbak"
+ */
+static const ItemInfo* previous_duplicated_item_id(const FileList* headFileList, const FileList* const curFileList, 
+        const ItemInfo* headItemInfo, const ItemInfo* curItemInfo)
+{
+    int itemId = -1;
+    int i = 0;
+
+    for(;headFileList != curFileList && headFileList->next; headFileList = headFileList->next)
+    {
+        int rc = strcmp(curFileList->name, headFileList->name);
+        if(!rc)//the file of headFileList is duplicated
+        {
+            for(; headItemInfo < curItemInfo; headItemInfo++)
+            {
+                if(!strcmp(headItemInfo->itemMainType, headFileList->main_type) 
+                        && !strcmp(headItemInfo->itemSubType, headFileList->sub_type))
+                {
+                    return headItemInfo;
+                }
+            }
+            errorP("find duplicated file(%s) but previous item not found\n", curFileList->name);
+            return NULL;
+        }
+    }
+
+    return NULL;
+}
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+int image_pack(const char* cfg_file, const char* src_dir ,const char* target_file)
+{
+       struct stat64 s;
+       FILE* fp_read = NULL;
+       FILE* fp_write  = NULL;
+       char *tmp;
+       int count = 0;
+    size_t write_bytes = 0;
+    ItemInfo* totalItemInfo = NULL;
+       char *buff = NULL;
+       int ret = 0;
+    ItemInfo*  AmlItem = NULL;
+
+       if(!cfg_file||!src_dir||!target_file){
+               fprintf(stderr,"invalid param! \n");
+               return -1;
+       }
+
+       if(stat64(cfg_file, &s)){
+               fprintf(stderr,"could not stat '%s'\n", cfg_file);
+               return -1;
+       }
+
+       fp_read = fopen(cfg_file, "rb");
+    if (fp_read == NULL){
+       fprintf(stderr,"failed to open canned file \n");
+       return -1;
+    }
+
+    tmp = (char*) malloc(s.st_size);
+    if(tmp == NULL) {
+       fprintf(stderr,"allocate memccpy failed  at %s  %d \n", __FILE__,__LINE__);
+       free(tmp);
+       return -1;
+    }
+
+    if(fread(tmp,1, s.st_size,fp_read) != s.st_size) {
+       fprintf(stderr,"file read error [%s] \n", strerror(errno));
+       fclose(fp_read);
+       free(tmp);
+       return -1;
+    }
+    fclose(fp_read);
+
+    if(image_cfg_parse(tmp,s.st_size) < 0){
+       fprintf(stderr,"image_cfg_parse error! \n");
+       free(tmp);
+       return -1;
+    }
+    free(tmp); tmp = NULL;
+
+    if(image_check_files(src_dir)<0){
+       fprintf(stderr,"image check file error! \n");
+       return -1;
+    }
+
+       fp_write = fopen(target_file, "wb+");
+       if (fp_write == NULL){
+               fprintf(stderr,"failed to create target file! \n");
+               return -1;
+       }
+    AmlFirmwareImg_t aAmlImage;
+       AmlFirmwareImg_t  *FirmwareImg = &aAmlImage;
+       memset(FirmwareImg,0,sizeof(AmlFirmwareImg_t));
+
+    if(fwrite(FirmwareImg,1, sizeof(AmlFirmwareImg_t),fp_write) != sizeof(AmlFirmwareImg_t)) {
+       fprintf(stderr,"cannot write %u bytes\n", (unsigned)sizeof(AmlFirmwareImg_t));
+       fclose(fp_write);
+       return -1;
+    }
+
+    const int TotalItemCnt = ImageDecoder->gItemCount;
+    debugP("TotalItemCnt %d\n", TotalItemCnt);
+    totalItemInfo = new ItemInfo[TotalItemCnt];
+
+       memset(totalItemInfo,0,sizeof(ItemInfo) * TotalItemCnt);
+    write_bytes = fwrite(totalItemInfo,1, sizeof(ItemInfo) * TotalItemCnt, fp_write);
+       if(write_bytes != sizeof(ItemInfo)* TotalItemCnt){
+        fprintf(stderr,"cannot write %d bytes \n", (int)sizeof(ItemInfo));
+        ret = __LINE__; goto _exit;
+    }
+
+       buff = new char[RW_MAX_SIZE];
+       if(buff==NULL){
+               fprintf(stderr,"allocate memccpy failed  at %s  %d \n", __FILE__,__LINE__);
+        ret = __LINE__; goto _exit;
+       }
+
+    //For each list:
+    //1, create item info;  2,pack the item data; 3, crate verify item info; 4, pack verify data
+    AmlItem = totalItemInfo;
+    for(const FileList *list = ImageDecoder->gImageCfg.file_list;
+            list; list = list->next, AmlItem++, count++)
+       {
+        struct stat64 info;
+        char path[256]={0};
+
+               memset(path,0,256);
+               strcpy(path,src_dir);
+               strcat(path,list->name);
+               printf("pack [%-12s, %16s] from (%s)\n", list->main_type, list->sub_type, path);
+
+        fp_read = fopen(path,"rb");
+        if(fp_read == NULL){
+            fprintf(stderr,"failed to open source file : %s \n",path);
+            ret = -1;
+            break;
+        }
+
+        if(stat64(path,&info)<0){
+                       fprintf(stderr,"stat %s failed!\n",path);
+                       ret =  -1;
+                       break;
+               }
+               AmlItem->itemSz = info.st_size;
+               AmlItem->itemId = count;
+               AmlItem->verify = 0;//1 if a verify item
+               strcpy(AmlItem->itemMainType,list->main_type);
+               strcpy(AmlItem->itemSubType,list->sub_type);
+
+        const ItemInfo* foundSamFileItemInfo = previous_duplicated_item_id(ImageDecoder->gImageCfg.file_list, list, totalItemInfo, AmlItem);
+        if(foundSamFileItemInfo)//this item is source from a duplicated file item
+        {
+            AmlItem->offsetInImage  = foundSamFileItemInfo->offsetInImage;
+            AmlItem->fileType       = foundSamFileItemInfo->fileType;
+            AmlItem->isBackUpItem   = 1;
+            AmlItem->backUpItemId   = foundSamFileItemInfo->itemId;
+        }
+        else
+        {
+            AmlItem->offsetInImage = ftello(fp_write);
+            if(AmlItem->offsetInImage % ITEM_ALGIN){
+                AmlItem->offsetInImage += ITEM_ALGIN - AmlItem->offsetInImage % ITEM_ALGIN;
+            }
+
+            fseeko(fp_read,0,SEEK_SET);
+            write_bytes = fread(buff,1,RW_MAX_SIZE,fp_read);
+            if(optimus_simg_probe(buff,RW_HEAD_SIZE) == 0){
+                AmlItem->fileType = IMAGE_ITEM_TYPE_NORMAL;
+            }else{
+                AmlItem->fileType = IMAGE_ITEM_TYPE_SPARSE;
+            }
+
+            //Following create the item data
+            //
+            fseeko(fp_write,AmlItem->offsetInImage,SEEK_SET);
+            fseeko(fp_read,0,SEEK_SET);
+            while((write_bytes = fread(buff,1,RW_MAX_SIZE,fp_read))>0)
+            {
+                if(fwrite(buff,1,write_bytes,fp_write)!=write_bytes){
+                    fprintf(stderr,"write to image file fail! [%s] \n",strerror(errno));
+                    ret = -1;
+                    break;
+                }
+            }
+            fclose(fp_read);
+            if(ret < 0)
+                break;
+        }
+
+               if(list->verify)
+               {
+            ++count;
+            ++AmlItem;
+
+                       AmlItem->itemSz = 48;
+                       AmlItem->itemId = count;
+                       strcpy(AmlItem->itemMainType,"VERIFY");
+                       strcpy(AmlItem->itemSubType,list->sub_type);
+                       AmlItem->fileType = IMAGE_ITEM_TYPE_NORMAL;
+                   AmlItem->verify = 1;
+
+            if(foundSamFileItemInfo)//the source file is already packed 
+            {
+                const ItemInfo* verfiyItem4_foundItem = foundSamFileItemInfo + 1;
+                //test if the next item following foundSamFileItemInfo is verify item
+                if(!strcmp(foundSamFileItemInfo->itemSubType, verfiyItem4_foundItem->itemSubType) 
+                        && !strcmp(verfiyItem4_foundItem->itemMainType, AmlItem->itemMainType))//"VERIFY"
+                {
+                    AmlItem->offsetInImage = verfiyItem4_foundItem->offsetInImage;
+                    AmlItem->isBackUpItem   = 1;
+                    AmlItem->backUpItemId   = verfiyItem4_foundItem->itemId;
+                    continue;//skip followings
+                }
+            }
+
+            AmlItem->offsetInImage = ftello(fp_write);
+            if(AmlItem->offsetInImage % ITEM_ALGIN){
+                AmlItem->offsetInImage += ITEM_ALGIN - AmlItem->offsetInImage % ITEM_ALGIN;
+            }
+
+                   memset(buff,0,48);
+                   gen_sha1sum_verify(path, buff);
+
+                   fseeko(fp_write,AmlItem->offsetInImage,SEEK_SET);
+                       if(fwrite(buff,1,48,fp_write)!=48){
+                               fprintf(stderr,"write verify data to image file fail! [%s] \n",strerror(errno));
+                               ret = -1;
+                               break;
+                       }
+               }
+       }
+       free(buff); buff = 0;
+
+       FirmwareImg->magic = IMAGE_MAGIC;
+       FirmwareImg->version = VERSION;
+
+       FirmwareImg->itemNum = count;
+       fseeko(fp_write, 0L, SEEK_END);
+       FirmwareImg->imageSz = ftello(fp_write);
+       FirmwareImg->itemAlginSize = 4;
+       fseeko(fp_write,0L,SEEK_SET);
+    if(fwrite(FirmwareImg,1, sizeof(AmlFirmwareImg_t),fp_write) != sizeof(AmlFirmwareImg_t)) {
+       fprintf(stderr,"cannot write %u bytes [%s] [0x%p]\n", 
+                (unsigned)sizeof(AmlFirmwareImg_t), strerror(errno), fp_write);
+       ret = -1;
+    }
+
+    write_bytes = fwrite(totalItemInfo, 1, sizeof(ItemInfo) * TotalItemCnt, fp_write);
+    if(write_bytes != sizeof(ItemInfo) * TotalItemCnt){
+        errorP("fail to update item info\n");
+        ret = __LINE__; goto _exit;
+    }
+
+       FirmwareImg->crc = calc_img_crc(fp_write,FirmwareImg->itemAlginSize);
+       fseeko(fp_write,0L,SEEK_SET);
+    if(fwrite(&(FirmwareImg->crc),1,FirmwareImg->itemAlginSize,fp_write) != FirmwareImg->itemAlginSize) {
+       fprintf(stderr,"cannot write crc32 [0x%x] [%s] \n",FirmwareImg->crc ,strerror(errno));
+       ret = -1;
+    }
+       printf("Size=0x%llxB[%lluM], crc=0x%x, Install image[%s] OK\n",
+            FirmwareImg->imageSz, (FirmwareImg->imageSz>>20), FirmwareImg->crc, target_file);
+
+_exit:
+    if(fp_write)fclose(fp_write), fp_write = NULL;
+    if(totalItemInfo)delete[] totalItemInfo, totalItemInfo = NULL;
+    if(buff) delete[] buff, buff = NULL;
+
+    return ret;
+}
+
+const char* const IMG_CFG_LINE = "file=\"%s.%s\"\t\tmain_type=\"%s\"\t\tsub_type=\"%s\"\r\n";
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+
+int image_unpack(const char* imagefile,const char *outpath)
+{
+       int ret = 0;
+       unsigned int itemCountTotal = 0;
+       unsigned int nItem = 0;
+       unsigned int write_bytes = 0;
+       char main_type[32] = {0};
+       char sub_type[32] = {0};
+       char outfile[512] = {0};
+       char cfgfile[128] = {0};
+       char buff[256] = {0};
+       
+       #ifdef BUILD_DLL
+       if(ImageDecoder->AmlFirmwareImg == NULL){
+               ImageDecoder->AmlFirmwareImg = (AmlFirmwareImg_t*)malloc(sizeof(AmlFirmwareImg_t));
+               if(ImageDecoder->AmlFirmwareImg == NULL){
+                       fprintf(stderr,"not enough memory\n");
+                       return -1;
+               }
+       }       
+       #endif
+       
+       if(outpath){
+               strcpy(outfile,outpath);
+               strcat(outfile,"\\");
+               strcpy(cfgfile,outfile);
+       }
+       strcat(cfgfile,"image.cfg");
+    
+       HIMAGE hImage = image_open(imagefile);
+       if(image_check(hImage) < 0){
+               fprintf(stderr,"the image check fail!!\n");
+               return -1;
+       }else{
+               printf("the image check ok!\n");
+       }
+
+    itemCountTotal = image_get_item_count(hImage,NULL);
+    const unsigned itemCountVerify = image_get_item_count(hImage, "VERIFY");
+    const unsigned itemCountNormal = itemCountTotal - itemCountVerify * 2;
+    debugP("item cnt:total[%u], normal[%u], verify[%u]\n", itemCountTotal, itemCountNormal, itemCountVerify);
+       
+    char *unPackBuf = (char*)malloc(RW_MAX_SIZE);
+    if(unPackBuf==NULL){
+        fprintf(stderr,"allocate memccpy failed  at %s  %d \n", __FILE__,__LINE__);
+        return __LINE__;
+    }
+
+    FILE *fp_cfg = fopen(cfgfile,"wb+");
+    if(fp_cfg==NULL){
+        fprintf(stderr,"create image.cfg failed ! [%s] \n",strerror(errno));
+        return __LINE__;
+    }
+    fwrite(TAG_NORMALLIST,1,strlen(TAG_NORMALLIST), fp_cfg);
+    fwrite("\r\n", 1, 2, fp_cfg);
+
+    for(nItem = 0; nItem < itemCountTotal; ++nItem)
+    {
+       if(image_get_next_item(hImage,nItem,main_type,sub_type) < 0){
+               ret = -1;
+               break;
+       }
+        if(!strcmp("VERIFY", main_type))
+        {
+            continue;//skip verify item
+        }
+        if(nItem == itemCountNormal)//[List_normal]ends, [List_verify] starts
+        {
+            fwrite("\r\n", 1, 2, fp_cfg);
+            fwrite(TAG_VERIFYLIST,1,strlen(TAG_VERIFYLIST), fp_cfg);
+            fwrite("\r\n", 1, 2, fp_cfg);
+        }
+
+       memset(outfile,0,64);
+       if(outpath){
+               strcpy(outfile,outpath);
+                       strcat(outfile,"/");
+       }
+
+       strcat(outfile,sub_type);
+       strcat(outfile,".");
+       strcat(outfile,main_type);
+       debugP("out file: %s  \n",outfile);//sub_type.main_type
+
+           HIMAGEITEM hItem = image_open_item(hImage,main_type,sub_type);
+           if(hItem == NULL){
+               fprintf(stderr,"open item[%s, %s] failed!\n", main_type, sub_type);
+               ret = -1;
+               break;
+           }
+
+        int backUpItemId = 0;
+        int itemIsBacked = is_item_backup_for_other_item(hItem, &backUpItemId);
+        if(itemIsBacked < 0){
+            errorP("Fail to in test is_item_backup_for_other_item\n");
+            ret = __LINE__; break;
+        }
+        if(itemIsBacked)//item is back item
+        {
+            char* CfgLine = (char*)unPackBuf;
+            char srcBackItemMainType[32];
+            char srcBackItemSubType[32];
+
+            if(image_get_next_item(hImage, backUpItemId, srcBackItemMainType, srcBackItemSubType)){
+                errorP("Fail to get the backui item head\n");
+                ret = __LINE__; break;
+            }
+            sprintf(CfgLine, IMG_CFG_LINE, srcBackItemSubType, srcBackItemMainType, main_type, sub_type);
+            fwrite(CfgLine,1,strlen(CfgLine), fp_cfg);
+            continue;
+        }
+
+       FILE *fp_out = fopen(outfile,"wb+");
+           if(fp_out == NULL){
+               fprintf(stderr,"failed to create out file : %s \n",outfile);
+                       ret = -1;
+                       break;
+           }
+
+           while((write_bytes = image_read_item_data(hImage, hItem, unPackBuf, RW_MAX_SIZE))>0)
+        {
+               if(fwrite(unPackBuf,1,write_bytes,fp_out)!=write_bytes){
+                       fprintf(stderr,"write to image file fail! [%s] \n",strerror(errno));
+                       ret = -1;
+                       break;
+               }
+           }
+           fclose(fp_out);
+           image_close_item(hItem);
+
+        char* CfgLine = (char*)unPackBuf;
+        sprintf(CfgLine, IMG_CFG_LINE, sub_type, main_type, main_type, sub_type);
+        fwrite(CfgLine,1,strlen(CfgLine), fp_cfg);
+    }
+    free(unPackBuf);
+    fclose(fp_cfg); fp_cfg = NULL;
+
+       #ifdef BUILD_DLL
+       if(ImageDecoder->AmlFirmwareImg){
+               free(ImageDecoder->AmlFirmwareImg);
+               ImageDecoder->AmlFirmwareImg = NULL;
+       }       
+       #endif
+       return ret;
+}
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+ImageDecoderIf_t* AmlImage_Init(){
+
+       ImageDecoder = (ImageDecoderIf_t*)malloc(sizeof(ImageDecoderIf_t));
+       memset(ImageDecoder,0,sizeof(ImageDecoderIf_t));
+       ImageDecoder->AmlFirmwareImg = (AmlFirmwareImg_t*)malloc(sizeof(AmlFirmwareImg_t));
+       if(ImageDecoder->AmlFirmwareImg == NULL){
+               fprintf(stderr,"not enough memory\n");
+               return NULL;
+       }
+       memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+       
+       ImageDecoder->img_open = image_open;
+       ImageDecoder->img_check = image_check;
+       ImageDecoder->img_close = image_close;
+       ImageDecoder->open_item = image_open_item;
+       ImageDecoder->close_item = image_close_item;
+       ImageDecoder->read_item = image_read_item_data;
+       ImageDecoder->item_seek = image_seek_item;
+       ImageDecoder->item_size = image_get_item_size;
+       ImageDecoder->item_type = image_get_item_type;
+       ImageDecoder->item_count = image_get_item_count;
+       ImageDecoder->get_next_item = image_get_next_item;
+       return ImageDecoder;
+}
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+void AmlImage_Final(ImageDecoderIf_t* pDecoder){
+
+
+       if(pDecoder){
+               if(pDecoder->AmlFirmwareImg){
+                       free(pDecoder->AmlFirmwareImg);
+                       pDecoder->AmlFirmwareImg = NULL;
+               }
+               free(pDecoder);
+       };
+}
+
+
+#ifndef BUILD_DLL
+
+static const char * const usage = "%s usage:\n\
+\n\
+  # pack files in directory to the archive\n\
+  %s -r <config file> <src dir> <target file> \n\
+  # unpack files in directory to the archive\n\
+  %s -d <archive> [out dir] \n\
+  # check the image    \n\
+  %s -c <archive>  \n";
+
+int main(int argc, char * const* argv)
+{
+       int ret = 0;
+       int c = 0;
+       const char* optstring = "d:r:c:";
+
+       
+       if(argc < 3||argc > 5) {
+               printf("invalid arguments argc==%d\n", argc);
+               fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+               exit(-1);
+       }
+
+       ImageDecoderIf_t* pDecoder = AmlImage_Init();
+
+    //for (int i = 1; i < argc; ++i)
+    {
+        const char* option = argv[1];
+        char* const*optarg = argv + 2;
+
+        if(!strcmp("-d", option))//unpack: argv[0] -d <archive> [out dir] 
+               {
+            const char* amlImg = optarg[0];
+            const char* unPackDir = optarg[1];
+                       if(access(amlImg,F_OK|R_OK) < 0){
+                               printf("Err:%s is not found! \n",amlImg);
+                return __LINE__;
+                       }
+                       if(argc == 4)
+                               ret = image_unpack(amlImg,unPackDir);
+                       else
+                               ret = image_unpack(amlImg,NULL);
+               }
+               else if(!strcmp("-r", option))//pack: argv[0] -r cfgFile workDir targetFile
+               {
+                       if(argc != 5){
+                               printf("invalid arguments argc==%d\n", argc);
+                               fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+                               exit(-1);
+                       }
+            const char* cfgFile = optarg[0];
+            const char* workdir = optarg[1];
+            const char* targetFile = optarg[2];
+                       if(access(cfgFile,F_OK|R_OK) < 0){
+                               fprintf(stderr,"Err:%s is not found! \n", cfgFile);
+                       }
+                       printf("image_pack cfg: %s\n", cfgFile);
+
+                       ret = image_pack(cfgFile, workdir, targetFile);
+               }
+               else if(!strcmp("-c", option))//check: argv[0] amlImage
+               {       
+            const char* amlImg = optarg[0];
+                       if(access(amlImg,F_OK|R_OK) < 0){
+                               fprintf(stderr,"Err:%s is not found!\n", amlImg);
+                       }
+                       FILE *fp = fopen(amlImg,"rb");
+                       if(image_check((HIMAGE) fp) < 0){
+                               fprintf(stderr,"the image check fail!!\n");
+                       }else{
+                               printf("the image check ok!\n");
+                       }
+                       fclose(fp);
+
+               }
+               else if(!strcmp("-?", option))
+               {
+                       fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+                       ret = -1;
+               }
+               else{
+                       fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+               }
+    }
+
+       AmlImage_Final(pDecoder);
+       return ret;
+}
+#endif// #ifndef BUILD_DLL
diff --git a/amlImage_if.h b/amlImage_if.h
new file mode 100644 (file)
index 0000000..504cf31
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * \file        amlImage_if.h
+ * \brief       Amlogic firmware image interface
+ *
+ * \version     1.0.0
+ * \date        2013/5/21
+ * \author      Sam.Wu <yihui.wu@Amlogic.com>
+ *
+ * Copyright (c) 2013 Amlogic Inc. All Rights Reserved.
+ *
+ */
+#ifndef __AMLIMAGE_IF_H__
+#define __AMLIMAGE_IF_H__
+
+#include <sys/types.h>
+
+#define AML_FIRMWARE_HEAD_SIZE      4096
+#define IMAGE_MAGIC                    0x27b51956       /* Image Magic Number          */
+#define VERSION                     0x0001
+#define AML_IMG_ITEM_INFO_SZ        (128)//Don't never change to keep compatibility
+#define AML_IMG_HEAD_INFO_SZ        (64)//Don't never change to keep compatibility
+
+typedef unsigned long long  __u64;
+typedef long long  __s64;
+typedef unsigned int        __u32;
+typedef int                 __s32;
+typedef unsigned short      __u16;
+typedef short               __s16;
+
+#pragma pack(push,4)
+typedef struct _AmlFirmwareItem_s
+{
+    __u32           itemId;
+    __u32           fileType;           //image file type, sparse and normal
+    __u64           curoffsetInItem;    //current offset in the item
+    __u64           offsetInImage;      //item offset in the image
+    __u64           itemSz;             //item size in the image
+    char            itemMainType[32];   //item main type and sub type used to index the item
+    char            itemSubType[32];    //item main type and sub type used to index the item
+    __u32           verify;
+    __u16           isBackUpItem;        //this item source file is the same as backItemId
+    __u16           backUpItemId;        //if 'isBackUpItem', then this is the item id
+    char            reserve[24];
+}ItemInfo;
+#pragma pack(pop)
+
+
+#pragma pack(push,4)
+typedef struct _AmlFirmwareImg_s
+{
+       __u32      crc;             //check sum of the image
+    __u32      version;         //firmware version
+    __u32      magic;           //magic No. to say it is Amlogic firmware image
+    __u64      imageSz;         //total size of this image file
+    __u32      itemAlginSize;   //align size for each item
+    __u32      itemNum;         //item number in the image, each item a file
+    char       reserve[36];
+}AmlFirmwareImg_t;
+#pragma pack(pop)
+
+
+
+typedef void* HIMAGE;
+typedef void* HIMAGEITEM;
+
+#define IMAGE_ITEM_TYPE_NORMAL  0
+#define IMAGE_ITEM_TYPE_SPARSE  0XFE
+
+
+//open a Amlogic firmware image
+//return value is a handle
+typedef HIMAGE (*func_img_open)(const char* );
+
+//check the image's crc32
+//return 0 when check ok,otherwise return -1
+typedef int (*func_img_check)(HIMAGE );
+
+//close a Amlogic firmware image
+typedef int (*func_img_close)(HIMAGE );
+
+//open a item in the image
+//@hImage: image handle;
+//@mainType, @subType: main type and subtype to index the item, such as ["IMAGE", "SYSTEM"]
+typedef HIMAGEITEM (*func_open_item)(HIMAGE , const char* , const char* );
+
+//close a item
+typedef int (*func_close_item)(HIMAGEITEM );
+
+typedef __u64 (*func_get_item_size)(HIMAGEITEM );
+
+
+//get image item type, current used type is normal or sparse
+typedef int (*func_get_item_type)(HIMAGEITEM );
+
+//get item count of specify main type
+typedef int (*func_get_item_count)(HIMAGE ,const char* );
+
+//read item data, like standard fread
+typedef __u32 (*func_read_item_data)(HIMAGE , HIMAGEITEM , void* , const __u32 );
+
+//relocate the read pointer to read the item data, like standard fseek
+typedef int (*func_item_seek)(HIMAGE , HIMAGEITEM , __s64 , __u32 );
+
+//get item main type and sub type
+typedef int (*func_get_next_item)(HIMAGE ,unsigned int , char* , char* );
+
+
+typedef struct filelist_t{
+       char name[128];
+       char main_type[32];
+       char sub_type[32];
+       int  verify;
+       struct filelist_t *next;
+}FileList;
+
+
+typedef struct image_cfg_t{
+       FileList *file_list;
+}ImageCfg;
+
+
+#pragma pack(push, 4)
+typedef struct _ImageDecoder_if
+{
+       int                     gItemCount;
+       ImageCfg                gImageCfg;
+       AmlFirmwareImg_t*       AmlFirmwareImg ;
+    func_img_open           img_open;      //open image
+       func_img_check          img_check;     //check image
+    func_img_close          img_close;     //close image
+    func_open_item          open_item;     //open a item in the image, like c library fopen
+    func_close_item         close_item;    //close a item, like c library fclose
+
+    func_read_item_data     read_item;     //read item data, like c library fread
+    func_item_seek          item_seek;     //seek the item read pointer, like c library fseek
+       func_get_item_size      item_size;     //get item size in byte
+       func_get_item_type      item_type;     //get item format, sparse, normal...
+       func_get_item_count     item_count;    //get item count of specify main type
+       func_get_next_item      get_next_item; //
+}ImageDecoderIf_t;
+#pragma pack(pop)
+
+#endif//ifndef __AMLIMAGE_IF_H__
+
diff --git a/crc32.cpp b/crc32.cpp
new file mode 100644 (file)
index 0000000..6827881
--- /dev/null
+++ b/crc32.cpp
@@ -0,0 +1,76 @@
+/*
+ * crc32.c
+ *
+ *  Created on: 2013-5-31
+ *      Author: binsheng.xu@amlogic.com
+ */
+#include "image_packer_i.h"
+
+#define BUFSIZE     1024*16
+
+static unsigned int crc_table[256];
+
+
+static void init_crc_table(void)
+{
+    unsigned int c;
+    unsigned int i, j;
+
+    for (i = 0; i < 256; i++) {
+        c = (unsigned int)i;
+        for (j = 0; j < 8; j++) {
+            if (c & 1)
+                c = 0xedb88320L ^ (c >> 1);
+            else
+                c = c >> 1;
+        }
+        crc_table[i] = c;
+    }
+}
+
+/*¼ÆËãbufferµÄcrcУÑéÂë*/
+static unsigned int crc32(unsigned int crc,unsigned char *buffer, unsigned int size)
+{
+    unsigned int i;
+    for (i = 0; i < size; i++) {
+        crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8);
+    }
+    return crc ;
+}
+
+/*
+**¼ÆËã´óÎļþµÄCRCУÑéÂë:crc32º¯Êý,ÊǶÔÒ»¸öbuffer½øÐд¦Àí,
+**µ«Èç¹ûÒ»¸öÎļþÏà¶Ô½Ï´ó,ÏÔÈ»²»ÄÜÖ±½Ó¶ÁÈ¡µ½ÄÚ´æµ±ÖÐ
+**ËùÒÔÖ»Äܽ«Îļþ·Ö¶Î¶ÁÈ¡³öÀ´½øÐÐcrcУÑé,
+**È»ºóÑ­»·½«ÉÏÒ»´ÎµÄcrcУÑéÂëÔÙ´«µÝ¸øеÄbufferУÑ麯Êý,
+**µ½×îºó£¬Éú³ÉµÄcrcУÑéÂë¾ÍÊǸÃÎļþµÄcrcУÑéÂë
+*/
+int calc_img_crc(FILE* fp, off_t offset)
+{
+
+    int nread;
+    unsigned char buf[BUFSIZE];
+    /*µÚÒ»´Î´«ÈëµÄÖµÐèÒª¹Ì¶¨,Èç¹û·¢ËͶËʹÓøÃÖµ¼ÆËãcrcУÑéÂë,
+    **ÄÇô½ÓÊÕ¶ËҲͬÑùÐèҪʹÓøÃÖµ½øÐмÆËã*/
+    unsigned int crc = 0xffffffff;
+
+    if (fp == NULL) {
+        fprintf(stderr,"bad param!!\n");
+        return -1;
+    }
+
+    init_crc_table();
+    fseeko(fp,offset,SEEK_SET);
+    while ((nread = fread(buf,1, BUFSIZE,fp)) > 0) {
+        crc = crc32(crc, buf, nread);
+    }
+
+    if (nread < 0) {
+        fprintf(stderr,"%d:read %s.\n", __LINE__, strerror(errno));
+        return -1;
+    }
+
+    return crc;
+}
+
+
diff --git a/crc32.h b/crc32.h
new file mode 100644 (file)
index 0000000..a609bc8
--- /dev/null
+++ b/crc32.h
@@ -0,0 +1,13 @@
+/*
+ * crc32.h
+ *
+ *  Created on: 2013-5-31
+ *      Author: binsheng.xu@amlogic.com
+ */
+
+#ifndef CRC32_H_
+#define CRC32_H_
+
+int calc_img_crc(FILE* fd, off_t offset);
+
+#endif /* CRC32_H_ */
diff --git a/dll.h b/dll.h
new file mode 100644 (file)
index 0000000..9a24ae7
--- /dev/null
+++ b/dll.h
@@ -0,0 +1,39 @@
+/*
+ * dll.h
+ *
+ *  Created on: 2013-6-3
+ *      Author: binsheng.xu@amlogic.com
+ */
+
+#ifndef DLL_H_
+#define DLL_H_
+
+#ifdef BUILD_DLL
+
+/* DLL export */
+
+#define EXPORT __declspec(dllexport)
+
+#else
+
+/* EXE import */
+
+#define EXPORT __declspec(dllimport)
+
+#endif
+
+#ifdef __cplusplus    // If used by C++ code, 
+//extern "C" {          // we need to export the C interface
+#endif
+
+EXPORT ImageDecoderIf_t* AmlImage_Init();
+EXPORT void AmlImage_Final(ImageDecoderIf_t* pDecoder);
+EXPORT int image_pack(const char* cfg_file,const char *src_dir ,const char* target_file);
+EXPORT int image_unpack(const char* imagefile,const char *outpath);
+
+
+#ifdef __cplusplus
+//}
+#endif
+
+#endif /* DLL_H_ */
diff --git a/image_packer.vcxproj b/image_packer.vcxproj
new file mode 100644 (file)
index 0000000..ddd6c1b
--- /dev/null
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Exe_Debug|Win32">
+      <Configuration>Exe_Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Exe_Release|Win32">
+      <Configuration>Exe_Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{FDC92709-02A2-496F-B62A-23FD0DFBC348}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>image_packer</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);BUILD_DLL</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);BUILD_DLL</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="amlImage.cpp" />
+    <ClCompile Include="crc32.cpp" />
+    <ClCompile Include="sha1.c" />
+    <ClCompile Include="sparse_format.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="amlImage_if.h" />
+    <ClInclude Include="crc32.h" />
+    <ClInclude Include="dll.h" />
+    <ClInclude Include="image_packer_i.h" />
+    <ClInclude Include="sha1.h" />
+    <ClInclude Include="sparse_format.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Android.mk" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/image_packer.vcxproj.filters b/image_packer.vcxproj.filters
new file mode 100644 (file)
index 0000000..5a6bac6
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="sha1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="amlImage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="crc32.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="sparse_format.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="amlImage_if.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crc32.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="sha1.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="sparse_format.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="dll.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="image_packer_i.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Android.mk" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/image_packer.vcxproj.user b/image_packer.vcxproj.user
new file mode 100644 (file)
index 0000000..a91c912
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'">
+    <LocalDebuggerCommandArguments>-r out/image.cfg out/ out.img</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/image_packer_i.h b/image_packer_i.h
new file mode 100644 (file)
index 0000000..00388c5
--- /dev/null
@@ -0,0 +1,45 @@
+/********************************************************************
+       created:        11-10-2013   15:43
+       file    :       image_packer_i.h
+       author:         Sam Wu
+       
+       purpose:        
+*********************************************************************/
+#ifndef __IMAGE_PACKER_I_H__
+#define __IMAGE_PACKER_I_H__
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#include <dirent.h>
+#ifdef BUILD_WITH_MINGW
+#define stat64  _stati64
+#define fseeko  fseeko64
+#define ftello  ftello64
+#endif
+#else//win32
+#include <io.h>
+#define stat64  _stati64
+#define fseeko  _fseeki64
+#define ftello  _ftelli64
+#define F_OK    0x00
+#define W_OK    0x02
+#define R_OK    0x04
+#endif// #ifndef WIN32
+
+#include "amlImage_if.h"
+#include "crc32.h"
+#include "sparse_format.h"
+
+#ifdef BUILD_DLL
+#include "dll.h"
+#endif
+
+#endif // __IMAGE_PACKER_I$_H__
diff --git a/sha1.c b/sha1.c
new file mode 100644 (file)
index 0000000..c148be2
--- /dev/null
+++ b/sha1.c
@@ -0,0 +1,537 @@
+/*
+ *  Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *  based on:
+ *  FIPS-180-1 compliant SHA-1 implementation
+ *
+ *  Copyright (C) 2003-2006  Christophe Devine
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License, version 2.1 as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include "image_packer_i.h"
+#include "sha1.h"
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i) {                         \
+       (n) = ( (unsigned long) (b)[(i)    ] << 24 )    \
+           | ( (unsigned long) (b)[(i) + 1] << 16 )    \
+           | ( (unsigned long) (b)[(i) + 2] <<  8 )    \
+           | ( (unsigned long) (b)[(i) + 3]       );   \
+}
+#endif
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i) {                         \
+       (b)[(i)    ] = (unsigned char) ( (n) >> 24 );   \
+       (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );   \
+       (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );   \
+       (b)[(i) + 3] = (unsigned char) ( (n)       );   \
+}
+#endif
+
+/*
+ * SHA-1 context setup
+ */
+void sha1_starts (sha1_context * ctx)
+{
+       ctx->total[0] = 0;
+       ctx->total[1] = 0;
+
+       ctx->state[0] = 0x67452301;
+       ctx->state[1] = 0xEFCDAB89;
+       ctx->state[2] = 0x98BADCFE;
+       ctx->state[3] = 0x10325476;
+       ctx->state[4] = 0xC3D2E1F0;
+}
+
+static void sha1_process (sha1_context * ctx, unsigned char data[64])
+{
+       unsigned long temp, W[16], A, B, C, D, E;
+
+       GET_UINT32_BE (W[0], data, 0);
+       GET_UINT32_BE (W[1], data, 4);
+       GET_UINT32_BE (W[2], data, 8);
+       GET_UINT32_BE (W[3], data, 12);
+       GET_UINT32_BE (W[4], data, 16);
+       GET_UINT32_BE (W[5], data, 20);
+       GET_UINT32_BE (W[6], data, 24);
+       GET_UINT32_BE (W[7], data, 28);
+       GET_UINT32_BE (W[8], data, 32);
+       GET_UINT32_BE (W[9], data, 36);
+       GET_UINT32_BE (W[10], data, 40);
+       GET_UINT32_BE (W[11], data, 44);
+       GET_UINT32_BE (W[12], data, 48);
+       GET_UINT32_BE (W[13], data, 52);
+       GET_UINT32_BE (W[14], data, 56);
+       GET_UINT32_BE (W[15], data, 60);
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t) (                                         \
+       temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
+              W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],  \
+       ( W[t & 0x0F] = S(temp,1) )                     \
+)
+
+#define P(a,b,c,d,e,x) {                               \
+       e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);    \
+}
+
+       A = ctx->state[0];
+       B = ctx->state[1];
+       C = ctx->state[2];
+       D = ctx->state[3];
+       E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+       P (A, B, C, D, E, W[0]);
+       P (E, A, B, C, D, W[1]);
+       P (D, E, A, B, C, W[2]);
+       P (C, D, E, A, B, W[3]);
+       P (B, C, D, E, A, W[4]);
+       P (A, B, C, D, E, W[5]);
+       P (E, A, B, C, D, W[6]);
+       P (D, E, A, B, C, W[7]);
+       P (C, D, E, A, B, W[8]);
+       P (B, C, D, E, A, W[9]);
+       P (A, B, C, D, E, W[10]);
+       P (E, A, B, C, D, W[11]);
+       P (D, E, A, B, C, W[12]);
+       P (C, D, E, A, B, W[13]);
+       P (B, C, D, E, A, W[14]);
+       P (A, B, C, D, E, W[15]);
+       P (E, A, B, C, D, R (16));
+       P (D, E, A, B, C, R (17));
+       P (C, D, E, A, B, R (18));
+       P (B, C, D, E, A, R (19));
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+       P (A, B, C, D, E, R (20));
+       P (E, A, B, C, D, R (21));
+       P (D, E, A, B, C, R (22));
+       P (C, D, E, A, B, R (23));
+       P (B, C, D, E, A, R (24));
+       P (A, B, C, D, E, R (25));
+       P (E, A, B, C, D, R (26));
+       P (D, E, A, B, C, R (27));
+       P (C, D, E, A, B, R (28));
+       P (B, C, D, E, A, R (29));
+       P (A, B, C, D, E, R (30));
+       P (E, A, B, C, D, R (31));
+       P (D, E, A, B, C, R (32));
+       P (C, D, E, A, B, R (33));
+       P (B, C, D, E, A, R (34));
+       P (A, B, C, D, E, R (35));
+       P (E, A, B, C, D, R (36));
+       P (D, E, A, B, C, R (37));
+       P (C, D, E, A, B, R (38));
+       P (B, C, D, E, A, R (39));
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+       P (A, B, C, D, E, R (40));
+       P (E, A, B, C, D, R (41));
+       P (D, E, A, B, C, R (42));
+       P (C, D, E, A, B, R (43));
+       P (B, C, D, E, A, R (44));
+       P (A, B, C, D, E, R (45));
+       P (E, A, B, C, D, R (46));
+       P (D, E, A, B, C, R (47));
+       P (C, D, E, A, B, R (48));
+       P (B, C, D, E, A, R (49));
+       P (A, B, C, D, E, R (50));
+       P (E, A, B, C, D, R (51));
+       P (D, E, A, B, C, R (52));
+       P (C, D, E, A, B, R (53));
+       P (B, C, D, E, A, R (54));
+       P (A, B, C, D, E, R (55));
+       P (E, A, B, C, D, R (56));
+       P (D, E, A, B, C, R (57));
+       P (C, D, E, A, B, R (58));
+       P (B, C, D, E, A, R (59));
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+       P (A, B, C, D, E, R (60));
+       P (E, A, B, C, D, R (61));
+       P (D, E, A, B, C, R (62));
+       P (C, D, E, A, B, R (63));
+       P (B, C, D, E, A, R (64));
+       P (A, B, C, D, E, R (65));
+       P (E, A, B, C, D, R (66));
+       P (D, E, A, B, C, R (67));
+       P (C, D, E, A, B, R (68));
+       P (B, C, D, E, A, R (69));
+       P (A, B, C, D, E, R (70));
+       P (E, A, B, C, D, R (71));
+       P (D, E, A, B, C, R (72));
+       P (C, D, E, A, B, R (73));
+       P (B, C, D, E, A, R (74));
+       P (A, B, C, D, E, R (75));
+       P (E, A, B, C, D, R (76));
+       P (D, E, A, B, C, R (77));
+       P (C, D, E, A, B, R (78));
+       P (B, C, D, E, A, R (79));
+
+#undef K
+#undef F
+
+       ctx->state[0] += A;
+       ctx->state[1] += B;
+       ctx->state[2] += C;
+       ctx->state[3] += D;
+       ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
+{
+       int fill;
+       unsigned long left;
+
+       if (ilen <= 0)
+               return;
+
+       left = ctx->total[0] & 0x3F;
+       fill = 64 - left;
+
+       ctx->total[0] += ilen;
+       ctx->total[0] &= 0xFFFFFFFF;
+
+       if (ctx->total[0] < (unsigned long) ilen)
+               ctx->total[1]++;
+
+       if (left && ilen >= fill) {
+               memcpy((void *) (ctx->buffer + left), (void *) input, fill);
+               sha1_process (ctx, ctx->buffer);
+               input += fill;
+               ilen -= fill;
+               left = 0;
+       }
+
+       while (ilen >= 64) {
+               sha1_process (ctx, input);
+               input += 64;
+               ilen -= 64;
+       }
+
+       if (ilen > 0) {
+               memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
+       }
+}
+
+static const unsigned char sha1_padding[64] = {
+       0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-1 final digest
+ */
+void sha1_finish (sha1_context * ctx, unsigned char output[20])
+{
+       unsigned long last, padn;
+       unsigned long high, low;
+       unsigned char msglen[8];
+
+       high = (ctx->total[0] >> 29)
+               | (ctx->total[1] << 3);
+       low = (ctx->total[0] << 3);
+
+       PUT_UINT32_BE (high, msglen, 0);
+       PUT_UINT32_BE (low, msglen, 4);
+
+       last = ctx->total[0] & 0x3F;
+       padn = (last < 56) ? (56 - last) : (120 - last);
+
+       sha1_update (ctx, (unsigned char *) sha1_padding, padn);
+       sha1_update (ctx, msglen, 8);
+
+       PUT_UINT32_BE (ctx->state[0], output, 0);
+       PUT_UINT32_BE (ctx->state[1], output, 4);
+       PUT_UINT32_BE (ctx->state[2], output, 8);
+       PUT_UINT32_BE (ctx->state[3], output, 12);
+       PUT_UINT32_BE (ctx->state[4], output, 16);
+}
+
+/*
+ * Output = SHA-1( input buffer )
+ */
+void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
+{
+       sha1_context ctx;
+
+       sha1_starts (&ctx);
+       sha1_update (&ctx, input, ilen);
+       sha1_finish (&ctx, output);
+}
+
+/*
+ * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
+ * bytes of input processed.
+ */
+void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
+                       unsigned int chunk_sz)
+{
+       sha1_context ctx;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+       unsigned char *end, *curr;
+       int chunk;
+#endif
+
+       sha1_starts (&ctx);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+       curr = input;
+       end = input + ilen;
+       while (curr < end) {
+               chunk = end - curr;
+               if (chunk > chunk_sz)
+                       chunk = chunk_sz;
+               sha1_update (&ctx, curr, chunk);
+               curr += chunk;
+               WATCHDOG_RESET ();
+       }
+#else
+       sha1_update (&ctx, input, ilen);
+#endif
+
+       sha1_finish (&ctx, output);
+}
+
+/*
+ * Output = HMAC-SHA-1( input buffer, hmac key )
+ */
+void sha1_hmac (unsigned char *key, int keylen,
+               unsigned char *input, int ilen, unsigned char output[20])
+{
+       int i;
+       sha1_context ctx;
+       unsigned char k_ipad[64];
+       unsigned char k_opad[64];
+       unsigned char tmpbuf[20];
+
+       memset (k_ipad, 0x36, 64);
+       memset (k_opad, 0x5C, 64);
+
+       for (i = 0; i < keylen; i++) {
+               if (i >= 64)
+                       break;
+
+               k_ipad[i] ^= key[i];
+               k_opad[i] ^= key[i];
+       }
+
+       sha1_starts (&ctx);
+       sha1_update (&ctx, k_ipad, 64);
+       sha1_update (&ctx, input, ilen);
+       sha1_finish (&ctx, tmpbuf);
+
+       sha1_starts (&ctx);
+       sha1_update (&ctx, k_opad, 64);
+       sha1_update (&ctx, tmpbuf, 20);
+       sha1_finish (&ctx, output);
+
+       memset (k_ipad, 0, 64);
+       memset (k_opad, 0, 64);
+       memset (tmpbuf, 0, 20);
+       memset (&ctx, 0, sizeof (sha1_context));
+}
+
+//static const char _sha1_src[] = "_sha1_src";
+
+#ifdef SELF_TEST
+/*
+ * FIPS-180-1 test vectors
+ */
+static const char sha1_test_str[3][57] = {
+       {"abc"},
+       {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
+       {""}
+};
+
+static const unsigned char sha1_test_sum[3][20] = {
+       {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
+        0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
+       {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
+        0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
+       {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
+        0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
+};
+
+/*
+ * Checkup routine
+ */
+int sha1_self_test (void)
+{
+       int i, j;
+       unsigned char buf[1000];
+       unsigned char sha1sum[20];
+       sha1_context ctx;
+
+       for (i = 0; i < 3; i++) {
+               printf ("  SHA-1 test #%d: ", i + 1);
+
+               sha1_starts (&ctx);
+
+               if (i < 2)
+                       sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
+                                    strlen (sha1_test_str[i]));
+               else {
+                       memset (buf, 'a', 1000);
+                       for (j = 0; j < 1000; j++)
+                               sha1_update (&ctx, buf, 1000);
+               }
+
+               sha1_finish (&ctx, sha1sum);
+
+               if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
+                       printf ("failed\n");
+                       return (1);
+               }
+
+               printf ("passed\n");
+       }
+
+       printf ("\n");
+       return (0);
+}
+#else
+int sha1_self_test (void)
+{
+       return (0);
+}
+#endif
+
+#define  Sha1Len  40
+
+int gen_sha1sum_verify(const char* srFile, char* verifyData)
+{
+    const int BufSz = 2U<<20;//2M
+    int ret = 0;
+    unsigned char* pBuf = NULL;
+    FILE* pSrcFile = 0;
+    //FILE* pDestFile = 0;
+    //unsigned wrLen = 0;
+    //const char prefix[] = "sha1sum ";
+    //const unsigned prefixLen = sizeof(prefix) - 1;
+    unsigned char genSumVal[Sha1Len/2 + 1] = {0};
+    //char sha1Result[Sha1Len + 1] = {0};
+       off_t SrcFileSz = 0;
+    sha1_context ctx;
+    off_t totalReadSz = 0;
+    off_t thisReadSz = 0;
+       struct stat s;
+    int i = 1;
+
+       if(stat(srFile, &s)){
+               printf("could not stat '%s'\n", srFile);
+               return -1;
+       }
+       SrcFileSz = s.st_size;
+    if(!SrcFileSz){
+        printf("Fail to get file size for file %s, is file path right??\n", srFile);
+        return __LINE__;
+    }
+
+
+    pSrcFile = fopen(srFile, "rb");
+    if(!pSrcFile){
+        printf("Fail to open src file\n");
+        return __LINE__;
+    }
+
+    pBuf = (unsigned char*)malloc(BufSz); //new unsigned char[BufSz];
+    if (!pBuf) {
+        printf("Fail to alloc buf\n");
+        fclose(pSrcFile);
+        return __LINE__;
+    }
+
+    sha1_starts(&ctx);
+
+    for(; totalReadSz < SrcFileSz; totalReadSz += thisReadSz)
+    {
+        unsigned readSz = 0;
+       off_t leftSz = SrcFileSz - totalReadSz;
+
+        thisReadSz = leftSz > BufSz ? BufSz : (unsigned)leftSz;
+
+        readSz = fread(pBuf, 1, thisReadSz, pSrcFile);
+        if(readSz != thisReadSz){
+            printf("Want to read 0x%ul, but 0x%ul \n", thisReadSz, readSz);
+            ret = __LINE__;
+            goto _finish;
+        }
+
+        sha1_update(&ctx, pBuf, thisReadSz);
+    }
+
+    free(pBuf);
+    pBuf = NULL;
+    fclose(pSrcFile);
+    pSrcFile = NULL;
+
+    sha1_finish(&ctx, genSumVal);
+    genSumVal[Sha1Len/2] = 0;
+    //printf("Gen sun raw value is \"%s\"\n", genSumVal);
+
+    sprintf(verifyData, "sha1sum %02x", genSumVal[0]);
+    for(; i < 20; ++i)
+    {
+        sprintf(verifyData, "%s%02x", verifyData, genSumVal[i]);
+    }
+
+    printf("gen sum for file %s is [%s]\n", srFile, verifyData);
+
+_finish:
+    if(pBuf)
+       free(pBuf);
+    if(pSrcFile)
+       fclose(pSrcFile);
+    return ret;
+}
+
+
+
diff --git a/sha1.h b/sha1.h
new file mode 100644 (file)
index 0000000..08727f1
--- /dev/null
+++ b/sha1.h
@@ -0,0 +1,118 @@
+/**
+ * \file sha1.h
+ * based from http://xyssl.org/code/source/sha1/
+ *  FIPS-180-1 compliant SHA-1 implementation
+ *
+ *  Copyright (C) 2003-2006  Christophe Devine
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License, version 2.1 as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301  USA
+ */
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+#ifndef _SHA1_H
+#define _SHA1_H
+
+#define SHA1_SUM_POS   -0x20
+#define SHA1_SUM_LEN   20
+
+/**
+ * \brief         SHA-1 context structure
+ */
+typedef struct
+{
+    unsigned long total[2];    /*!< number of bytes processed  */
+    unsigned long state[5];    /*!< intermediate digest state  */
+    unsigned char buffer[64];  /*!< data block being processed */
+}
+sha1_context;
+
+/**
+ * \brief         SHA-1 context setup
+ *
+ * \param ctx     SHA-1 context to be initialized
+ */
+void sha1_starts( sha1_context *ctx );
+
+/**
+ * \brief         SHA-1 process buffer
+ *
+ * \param ctx     SHA-1 context
+ * \param input    buffer holding the  data
+ * \param ilen    length of the input data
+ */
+void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
+
+/**
+ * \brief         SHA-1 final digest
+ *
+ * \param ctx     SHA-1 context
+ * \param output   SHA-1 checksum result
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief         Output = SHA-1( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen    length of the input data
+ * \param output   SHA-1 checksum result
+ */
+void sha1_csum( unsigned char *input, int ilen,
+               unsigned char output[20] );
+
+/**
+ * \brief         Output = SHA-1( input buffer ), with watchdog triggering
+ *
+ * \param input    buffer holding the  data
+ * \param ilen    length of the input data
+ * \param output   SHA-1 checksum result
+ * \param chunk_sz watchdog triggering period (in bytes of input processed)
+ */
+void sha1_csum_wd (unsigned char *input, int ilen,
+               unsigned char output[20], unsigned int chunk_sz);
+
+/**
+ * \brief         Output = SHA-1( file contents )
+ *
+ * \param path    input file name
+ * \param output   SHA-1 checksum result
+ * \return        0 if successful, or 1 if fopen failed
+ */
+int sha1_file( char *path, unsigned char output[20] );
+
+/**
+ * \brief         Output = HMAC-SHA-1( input buffer, hmac key )
+ *
+ * \param key     HMAC secret key
+ * \param keylen   length of the HMAC key
+ * \param input    buffer holding the  data
+ * \param ilen    length of the input data
+ * \param output   HMAC-SHA-1 result
+ */
+void sha1_hmac( unsigned char *key, int keylen,
+               unsigned char *input, int ilen,
+               unsigned char output[20] );
+
+/**
+ * \brief         Checkup routine
+ *
+ * \return        0 if successful, or 1 if the test failed
+ */
+int sha1_self_test( void );
+
+#endif /* sha1.h */
diff --git a/sparse_format.cpp b/sparse_format.cpp
new file mode 100644 (file)
index 0000000..b2fa098
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * sparse_format.c
+ *
+ *  Created on: 2013-6-3
+ *      Author: binsheng.xu@amlogic.com
+ */
+
+//ÅжÏÎļþ¸ñʽÊÇ·ñΪsparse
+#include <stdio.h>
+#include "sparse_format.h"
+
+//0 is not sparse packet header, else is sparse packet_header
+int optimus_simg_probe(const char* source, const __u32 length)
+{
+       sparse_header_t *header = (sparse_header_t*) source;
+
+    if(length < sizeof(sparse_header_t)) {
+       fprintf(stderr,"length %d < sparse_header_t len %d\n", length, FILE_HEAD_SIZE);
+        return 0;
+    }
+       if (header->magic != SPARSE_HEADER_MAGIC) {
+               //fprintf(stderr,"sparse bad magic, expect 0x%x but 0x%x\n", SPARSE_HEADER_MAGIC, header->magic);
+               return 0;
+       }
+
+    if(!(SPARSE_HEADER_MAJOR_VER == header->major_version
+                && FILE_HEAD_SIZE == header->file_hdr_sz
+                && CHUNK_HEAD_SIZE == header->chunk_hdr_sz))
+    {
+        fprintf(stderr,"want 0x [%x, %x, %x], but [%x, %x, %x]\n",
+                SPARSE_HEADER_MAJOR_VER,    FILE_HEAD_SIZE,             CHUNK_HEAD_SIZE,
+                header->major_version,      header->file_hdr_sz,        header->chunk_hdr_sz);
+        return 0;
+    }
+       return 1;
+}
+
diff --git a/sparse_format.h b/sparse_format.h
new file mode 100644 (file)
index 0000000..20137cd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "amlImage_if.h"
+
+typedef struct sparse_header {
+  __u32        magic;               /* 0xed26ff3a */
+  __u16        major_version;  /* (0x1) - reject images with higher major versions */
+  __u16        minor_version;  /* (0x0) - allow images with higer minor versions */
+  __u16        file_hdr_sz;    /* 28 bytes for first revision of the file format */
+  __u16        chunk_hdr_sz;   /* 12 bytes for first revision of the file format */
+  __u32        blk_sz;         /* block size in bytes, must be a multiple of 4 (4096) */
+  __u32        total_blks;     /* total blocks in the non-sparse output image */
+  __u32        total_chunks;   /* total chunks in the sparse input image */
+  __u32        image_checksum; /* CRC32 checksum of the original data, counting "don't care" */
+                               /* as 0. Standard 802.3 polynomial, use a Public Domain */
+                               /* table implementation */
+} sparse_header_t;
+
+#define SPARSE_HEADER_MAGIC    0xed26ff3a
+
+#define CHUNK_TYPE_RAW         0xCAC1
+#define CHUNK_TYPE_FILL                0xCAC2
+#define CHUNK_TYPE_DONT_CARE   0xCAC3
+#define CHUNK_TYPE_CRC32    0xCAC4
+
+typedef struct chunk_header {
+  __u16        chunk_type;     /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
+  __u16        reserved1;
+  __u32        chunk_sz;       /* in blocks in output image */
+  __u32        total_sz;       /* in bytes of chunk input file including chunk header and data */
+} chunk_header_t;
+
+/* Following a Raw or Fill or CRC32 chunk is data.
+ *  For a Raw chunk, it's the data in chunk_sz * blk_sz.
+ *  For a Fill chunk, it's 4 bytes of the fill data.
+ *  For a CRC32 chunk, it's 4 bytes of CRC32
+ */
+
+#define  SPARSE_HEADER_MAJOR_VER   1
+#define  CHUNK_HEAD_SIZE           sizeof(chunk_header_t)
+#define  FILE_HEAD_SIZE            sizeof(sparse_header_t)
+
+int optimus_simg_probe(const char* source, const __u32 length);
+
+
+