summaryrefslogtreecommitdiff
path: root/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp')
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp1102
1 files changed, 1102 insertions, 0 deletions
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp
new file mode 100644
index 0000000..393880b
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp
@@ -0,0 +1,1102 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "regex.h"
+#include "EasyBMP.h"
+#include "ScriptParse.h"
+#include "DemoBinHeader.h"
+#include "CreateDemoBin.h"
+
+using namespace std;
+
+#define _GNU_SOURCE
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//variable used
+//////////////////////////////////////////////////////////////////////////////////////////
+
+//slide bmp file name array
+static char pptSlidesBmp[MAXSLIDESPERBIN][256];
+//converted slide bmp file name array;
+static char pptSlidesResizedBmp[MAXSLIDESPERBIN][256];
+
+//generated PPT information txt file,default set as Sam3DEMO.txt
+//will be changed based execution argument
+static char pptScriptLink[256] = "Sam3DEMO.txt";
+//generated demo bin file name
+//will be changed based on execution argument
+static char pAtmlDemoBin[256] = "Sam3DEMO.bin";
+//temp file to link all bitmap file, used during creation,will be removed
+//in the end of conversion
+static char pBinContent[256] = "Sam3DEMOContent.tmp";
+
+//variables for parsing script file
+static char line[6*MAXSCRIPTSTRINGLINE];//[6][128];
+static unsigned int slidecnt, slidewidth, slideheight;
+static unsigned int linkcnt, linktop, linkleft, linkwidth, linkheight;
+static unsigned int dispboxtop, dispboxleft, dispboxwidth, dispboxheight;
+static char linkaddr[MAXLINKLEN];
+static char oninitcmds[MAXLINKLEN], onrefreshcmds[MAXLINKLEN], onclosecmds[MAXLINKLEN];
+
+//used to count slides parsed.
+static unsigned int loop=0;
+//binfile header
+static DemoBINHeader binhead;
+//each slide information. valid count is binhead.slidecount
+static SlideINFOHeader slideinfo[MAXSLIDESPERBIN];
+//used to store parsed slides index for reading slide bmp file
+static unsigned int parsedslides[MAXSLIDESPERBIN];
+
+//////////////////////////////////////////////////////////////////////////////////
+//Internal function
+/////////////////////////////////////////////////////////////////////////////////
+
+//rotate BMP with clockwise angel 90 degree
+static bool Rotate90(BMP &Input, BMP &Output)
+{
+ bool bRet = true;
+ int srcHeight = Input.TellHeight();
+ int srcWidth = Input.TellWidth();
+
+ bRet &= Output.SetSize(srcHeight,srcWidth);
+
+ for(int xpos = 0;xpos < srcWidth; xpos++)
+ {
+ for(int ypos=0;ypos<srcHeight;ypos++)
+ {
+ bRet &= Output.SetPixel(srcHeight-1-ypos,xpos,Input.GetPixel(xpos,ypos));
+ }
+ }
+
+ return bRet;
+}
+
+//Rotate BMP with clockwise angel 180 degree
+static bool Rotate180(BMP &Input, BMP &Output)
+{
+ bool bRet = true;
+ int srcHeight = Input.TellHeight();
+ int srcWidth = Input.TellWidth();
+
+ bRet &= Output.SetSize(srcWidth,srcHeight);
+
+ for(int xpos = 0;xpos < srcWidth; xpos++)
+ {
+ for(int ypos=0;ypos<srcHeight;ypos++)
+ {
+ bRet &= Output.SetPixel(srcWidth-1-xpos,srcHeight-1-ypos,Input.GetPixel(xpos,ypos));
+ }
+ }
+
+ return bRet;
+}
+
+//Rotate BMP with clockwise angel 270 degree
+static bool Rotate270(BMP &Input, BMP &Output)
+{
+ bool bRet = true;
+ int srcHeight = Input.TellHeight();
+ int srcWidth = Input.TellWidth();
+
+ bRet &= Output.SetSize(srcHeight,srcWidth);
+
+ for(int xpos = 0;xpos < srcWidth; xpos++)
+ {
+ for(int ypos=0;ypos<srcHeight;ypos++)
+ {
+ bRet &= Output.SetPixel(ypos,srcWidth-1-xpos,Input.GetPixel(xpos,ypos));
+ }
+ }
+
+ return bRet;
+}
+
+//rotate bmp file with clockwise angel
+static bool Rotate(char *pInBmp, char *pOutBmp, unsigned int angle)
+{
+ bool bRet=false;
+
+ //no need to do anything for 0,360,720...
+ if(angle % 360 == 0) {
+ return true;
+ }
+
+ BMP Input;
+ Input.ReadFromFile(pInBmp);
+ BMP Output;
+ Output.SetBitDepth(Input.TellBitDepth());
+
+ switch(angle) {
+ case 90:
+ bRet = Rotate90(Input, Output);
+ break;
+
+ case 180:
+ bRet = Rotate180(Input,Output);
+ break;
+
+ case 270:
+ bRet = Rotate270(Input,Output);
+ break;
+
+ default:
+ fprintf(stderr, "\n\r Sorry, rotation angle other than 90,180,270 is not supported yet!");
+ bRet = false;
+ break;
+ }
+
+ if(bRet)
+ bRet &= Output.WriteToFile(pOutBmp);
+
+ return bRet;
+}
+
+//Read a not empty string line from file
+static bool GetLineNoEmpty(FILE *fp, char *buf, size_t len)
+{
+ char *str=NULL;
+
+ do {
+ str = fgets(buf, len, fp);
+
+ if(!str) {
+ //fprintf(stderr, "\n\rFail to get a line!");
+ return false;
+ }
+ }while(IsSpaceLine(buf));
+
+ return true;
+}
+
+//convert a box zone coordinate based on rotate angle and coordinate origin
+//input coordinate value use upper left as (0,0) coordinate origin
+static bool HotZoneCoordinateConversion(
+ //following four params define a box zone
+ //value is in unresized coordinate, origin point is UPPER_LEFT
+ unsigned int raw_zone_top,
+ unsigned int raw_zone_left,
+ unsigned int raw_zone_width,
+ unsigned int raw_zone_height,
+ //following four param discribe
+ unsigned int resizedwidth,
+ unsigned int resizedheight,
+ double widthresizeratio,
+ double heightresizeratio,
+ //clockwise rotate angle
+ unsigned int rotateangle,
+ //coordinate origin remap, input values use PIC UPPER_LEFT as origin point
+ unsigned int *out_zone_bottom,
+ unsigned int *out_zone_left,
+ unsigned int *out_zone_width,
+ unsigned int *out_zone_height)
+{
+ unsigned int resizedzonetop, resizedzoneleft, resizedzonewidth, resizedzoneheight;
+ unsigned int rotatedzonetop, rotatedzoneleft, rotatedzonewidth, rotatedzoneheight;
+
+ resizedzonetop = (unsigned int)(raw_zone_top * heightresizeratio);
+ resizedzoneleft = (unsigned int)(raw_zone_left * widthresizeratio);
+ resizedzonewidth = (unsigned int)(raw_zone_width * widthresizeratio);
+ resizedzoneheight = (unsigned int)(raw_zone_height * heightresizeratio);
+
+ switch(rotateangle) {
+ case 0:
+ rotatedzonetop = resizedzonetop;
+ rotatedzoneleft = resizedzoneleft;
+ rotatedzonewidth = resizedzonewidth;
+ rotatedzoneheight = resizedzoneheight;
+ break;
+ case 90:
+ rotatedzonetop = resizedwidth - (resizedzoneleft + resizedzonewidth);
+ rotatedzoneleft = resizedheight - (resizedzonetop + resizedzoneheight);
+ rotatedzonewidth = resizedzoneheight;
+ rotatedzoneheight = resizedzonewidth;
+ break;
+ case 180:
+ rotatedzonetop = resizedheight - (resizedzonetop + resizedzoneheight);
+ rotatedzoneleft = resizedwidth - (resizedzoneleft + resizedzonewidth);
+ rotatedzonewidth = resizedzonewidth;
+ rotatedzoneheight = resizedzoneheight;
+ break;
+ case 270:
+ rotatedzonetop = resizedwidth - (resizedzoneleft + resizedzonewidth);
+ rotatedzoneleft = resizedzonetop;
+ rotatedzonewidth = resizedzoneheight;
+ rotatedzoneheight = resizedzonewidth;
+ break;
+ case 360:
+ rotatedzonetop = resizedzonetop;
+ rotatedzoneleft = resizedzoneleft;
+ rotatedzonewidth = resizedzonewidth;
+ rotatedzoneheight = resizedzoneheight;
+ break;
+ default:
+ fprintf(stderr, "\n Sorry, rotate angle other than 0, 90, 180, 270,360 not supported yet!");
+ return false;
+ }
+
+ if(out_zone_bottom && out_zone_left && out_zone_width && out_zone_height) {
+ *out_zone_bottom = rotatedzonetop + rotatedzoneheight;
+ *out_zone_left = rotatedzoneleft;
+ *out_zone_width = rotatedzonewidth;
+ *out_zone_height = rotatedzoneheight;
+ }else {
+ fprintf(stderr, "\n One of output param point is null in HotZoneCoordinateConversion(...)!");
+ return false;
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//Export functions:
+// Steps to Create demo bin
+////////////////////////////////////////////////////////////////////////////////////
+
+//Initialize filename variables
+void Step1_CreateFileNameVars(char * name)
+{
+ sprintf(pptScriptLink, "%s.txt", name);
+
+ for(int i = 0; i < MAXSLIDESPERBIN; ++i) {
+ #if !defined(MOVIE_MERGE_on)
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\slide%d.bmp",name, i+1);
+ #else
+ if(i<9 && i>=0){
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\speedway_loop_medium00%d.bmp",name, i+1);
+ } else if (i <99) {
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\speedway_loop_medium0%d.bmp",name, i+1);
+ } else{
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\speedway_loop_medium%d.bmp",name, i+1);
+ }
+ printf("\n\r name: %s", &pptSlidesBmp[i][0]);
+ #endif
+ }
+
+ for(int j = 0; j < MAXSLIDESPERBIN; ++j) {
+ sprintf(&pptSlidesResizedBmp[j][0], "%s\\\\slide%d_resized.bmp", name, j+1);
+ }
+
+ sprintf(pBinContent, "%scontent.tmp", name);
+ sprintf(pAtmlDemoBin, "%s.bin", name);
+
+}
+
+//Process ppt information txt file
+bool Step2_ProcessPPTInfoFile(BMPConvOpt *pOption)
+{
+ //open script file to process
+ FILE *pScriptfile = fopen(pptScriptLink, "rb");
+ if(!pScriptfile)
+ {
+ fclose(pScriptfile);
+ fprintf(stderr, "\n\r Open ppt info txt file %s for creating demo bin fails!", pptScriptLink);
+ return false;
+ }
+
+ //compile all regex pattern, if fail return
+ if(!CompileAllPtn()) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Compilation pattern fails!");
+ return false;
+ }
+
+ //clear all fields with 0xFF
+ ClearDemoBINHeader(&binhead);
+ for(int i=0;i<MAXSLIDESPERBIN;++i){
+ ClearSlideINFOHeader(&slideinfo[i]);// use 0xFF to clear, considering flash using 0xff as raw data
+ }
+
+ //clear count fields as 0
+ binhead.slidecount = 0;
+ for(int i=0;i<MAXSLIDESPERBIN;++i){
+ slideinfo[i].linkcount = 0;
+ slideinfo[i].dispboxcount = 0;//default 0 means no display box
+ slideinfo[i].propyes = 0; //default 0 means no properties settings
+ }
+
+ //read first line of script file
+ if(!GetLineNoEmpty(pScriptfile, line, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Fail to read a effective string line from script file !");
+ return false;
+ }
+
+ //check first line if it match start of slide section
+ if(!IsSlideSectionStart(line)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide section starting!");
+ return false;
+ }
+
+ //start loop of parsing script
+ for(loop = 0;loop < MAXSLIDESPERBIN ;++loop) {
+
+ //read slide section from script file, 4 lines information each slide section
+ for(int i = 1; i < 4; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide section!");
+ return false;
+ }
+ }
+
+ //parse slide section, to get slide count, slide width, slide height
+ if(!ParseSlideSection(line, &slidecnt, &slidewidth, &slideheight)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide section!");
+ return false;
+ }
+
+ //a slide section found, set some fields.
+ //width and height gotten above will be used to calculating resized link box
+ //gotten slide count will be used to index file name
+ ++binhead.slidecount;
+ if(binhead.slidecount > MAXSLIDESPERBIN){
+ //reach max slide per bin
+ binhead.slidecount = MAXSLIDESPERBIN;
+ break;
+ }
+
+ parsedslides[loop]= slidecnt - 1;//record file index in the file name array
+
+ //store temp, as index to file name array, slides index in bin file not depends on this
+ //parsedslides[binhead.slidecount - 1] = slidecnt;//store temp, as index to file name array
+
+ //if rotate angle is times of 180 degree, then no need to switch width and height
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ if(pOption->rotateangle % 180 == 0){
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->width;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->height;//fixed for demo
+ } else if(pOption->rotateangle % 90 == 0) {
+ //if rotate angle is times of 90 degree, but not times of 2*90 degree,
+ //then switch width and height
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->height;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->width;//fixed for demo
+ } else {
+ fprintf(stderr, "\n Sorry, rotate angle %u not supported for coordinate conversion!", pOption->rotateangle);
+ fclose(pScriptfile);
+ FreeAllRegex();
+ return false;
+ }
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else {
+ if(pOption->ssRotateangle % 180 == 0){
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->ssWidth;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->ssHeight;//fixed for demo
+ } else if(pOption->ssRotateangle % 90 == 0) {
+ //if rotate angle is times of 90 degree, but not times of 2*90 degree,
+ //then switch width and height
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->ssHeight;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->ssWidth;//fixed for demo
+ } else {
+ fprintf(stderr, "\n Sorry, rotate angle %u not supported for coordinate conversion!", pOption->ssRotateangle);
+ fclose(pScriptfile);
+ FreeAllRegex();
+ return false;
+ }
+ }
+ #endif
+
+ //parse each slide info field,i.e. display box, hyperlink, property config section for now
+ for(;;) {
+ //read available line in ppt information txt file
+ if(!GetLineNoEmpty(pScriptfile, line, MAXSCRIPTSTRINGLINE)) {
+ if(feof(pScriptfile)) {
+ //end of file
+ printf("\n\r OK, reach script file end!");
+ fclose(pScriptfile);
+ FreeAllRegex();
+ return true;
+ }
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide info organization!");
+ return false;
+ }
+
+ //
+ //Is it slide section?
+ //
+ if(IsSlideSectionStart(line))
+ break;//yes, break parsing slide info loop and goto next loop of parsing slide section
+
+ //
+ //Is it slide properties section?
+ //
+ if(IsPropertiesSectionStart(line)) {
+ //
+ //Note: Ony 1 properties field in bin file,
+ // So only the lastest properties section content will be recorded!!!
+ //
+
+ //properties section, read remained section string lines
+ for(int i = 1; i < 4; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for 'Properties' section!");
+ return false;
+ }
+ }
+
+ if(!ParsePropertiesSection(line, \
+ oninitcmds, \
+ onrefreshcmds, \
+ onclosecmds)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not righ for slide 'Properties' section!");
+ return false;
+ }
+
+ //setting flag to indicate having property settings for this slide
+ slideinfo[binhead.slidecount - 1].propyes = 1;
+ slideinfo[binhead.slidecount - 1].propinfo.propcnt = 3;
+ strcpy(slideinfo[binhead.slidecount - 1].propinfo.onInitCmds, oninitcmds);
+ strcpy(slideinfo[binhead.slidecount - 1].propinfo.onRefreshCmds, onrefreshcmds);
+ strcpy(slideinfo[binhead.slidecount - 1].propinfo.onCloseCmds, onclosecmds);
+
+ continue;
+ }
+
+ //
+ //Is it Display box section?
+ //
+ if(IsDispBoxSectionStart(line)) {
+ //display box section, read remained section string lines
+ for(int i = 1; i < 5; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for 'DisplayBox' section!");
+ return false;
+ }
+ }
+
+ //parse display box section
+ if(!ParseDispBoxSection(line, \
+ &dispboxtop, &dispboxleft, &dispboxwidth, &dispboxheight)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for 'DisplayBox' section!");
+ return false;
+ }
+
+ //have display box in slide
+ ++slideinfo[binhead.slidecount - 1].dispboxcount;
+ if(slideinfo[binhead.slidecount - 1].dispboxcount > MAX_DISPBOX_PER_SLIDE) {
+ //reach max display box for a slide
+ slideinfo[binhead.slidecount - 1].dispboxcount = MAX_DISPBOX_PER_SLIDE;
+ continue;
+ }
+
+ //resized ratio
+ double width_ratio;
+ double height_ratio;
+ unsigned int conv_bottom, conv_left, conv_width, conv_height;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ width_ratio = pOption->width / (double)slidewidth;
+ height_ratio = pOption->height / (double)slideheight;
+
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ width_ratio = pOption->ssWidth / (double)slidewidth;
+ height_ratio = pOption->ssHeight / (double)slideheight;
+ }
+ #endif
+
+ unsigned int tmpRet;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ tmpRet = HotZoneCoordinateConversion(
+ dispboxtop,
+ dispboxleft,
+ dispboxwidth,
+ dispboxheight,
+ pOption->width,
+ pOption->height,
+ width_ratio,
+ height_ratio,
+ pOption->rotateangle,
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ tmpRet = HotZoneCoordinateConversion(
+ dispboxtop,
+ dispboxleft,
+ dispboxwidth,
+ dispboxheight,
+ pOption->ssWidth,
+ pOption->ssHeight,
+ width_ratio,
+ height_ratio,
+ pOption->ssRotateangle,
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ }
+ #endif
+ if(!tmpRet)
+ {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n Script file format is not right!");
+ return false;
+ }
+ unsigned int slideindex = binhead.slidecount - 1;
+ unsigned int dispboxindex = slideinfo[binhead.slidecount-1].dispboxcount - 1;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxbottom = conv_bottom;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxleft = conv_left;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxwidth = conv_width;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxheight = conv_height;
+
+ continue;
+ }
+
+ //
+ //Is it hyperlink section?
+ //
+ if(IsLinkSectionStart(line)) {
+
+ //hyperlink section, read remained section string lines
+ for(int i = 1; i < 6; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right!");
+ return false;
+ }
+ }
+
+ //parse hyperlink section
+ if(!ParseLinkSection(line, &linkcnt, linkaddr, \
+ &linktop, &linkleft, &linkwidth, &linkheight)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right!");
+ return false;
+ }
+
+ //parsed linkcnt is not used, considering if some links were removed by manual
+ ++(slideinfo[binhead.slidecount - 1].linkcount);
+ if(slideinfo[binhead.slidecount - 1].linkcount > MAX_LINK_PER_SLIDE) {
+ //reach max link limit for a slide
+ slideinfo[binhead.slidecount - 1].linkcount = MAX_LINK_PER_SLIDE;
+ continue;
+ }
+
+ //resize ratio
+ double width_ratio;
+ double height_ratio;
+ unsigned int conv_bottom, conv_left, conv_width, conv_height;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ width_ratio = pOption->width / (double)slidewidth;
+ height_ratio = pOption->height / (double)slideheight;
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ width_ratio = pOption->ssWidth / (double)slidewidth;
+ height_ratio = pOption->ssHeight / (double)slideheight;
+ }
+ #endif
+ //printf("\n linktop %u, linkleft %u, linkwidth %u, linkheight %u",\
+ // linktop, linkleft, linkwidth, linkheight);
+ unsigned int tmpRet;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ tmpRet = HotZoneCoordinateConversion(
+ //original link zone params, gotten from slide info txt file
+ linktop,
+ linkleft,
+ linkwidth,
+ linkheight,
+ //resized slide width and height
+ pOption->width,
+ pOption->height,
+ //resize ratio of width and height
+ width_ratio,
+ height_ratio,
+ //clockwise rotate angle
+ pOption->rotateangle,
+ //pointer of output link zone param
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ tmpRet = HotZoneCoordinateConversion(
+ //original link zone params, gotten from slide info txt file
+ linktop,
+ linkleft,
+ linkwidth,
+ linkheight,
+ //resized slide width and height
+ pOption->ssWidth,
+ pOption->ssHeight,
+ //resize ratio of width and height
+ width_ratio,
+ height_ratio,
+ //clockwise rotate angle
+ pOption->ssRotateangle,
+ //pointer of output link zone param
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ }
+ #endif
+ if(!tmpRet)
+ {
+ //link hot zone coordinate conversion fail, then return false
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n Link zone coordinate conversion fail!");
+ return false;
+ }
+
+ //set the slideinfo link value, noted bmp was rotated and resized.
+ unsigned int linkindex = slideinfo[binhead.slidecount-1].linkcount - 1;
+ unsigned int slideindex = binhead.slidecount - 1;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxbottom = conv_bottom;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxleft = conv_left;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxwidth = conv_width;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxheight = conv_height;
+
+#ifdef DEBUG_LINKSECTION
+ printf("\n\r [slide %d, link box %d is %u, %u, %u, %u,addr %s]", slideindex, linkindex,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxbottom,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxleft,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxwidth,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxheight, \
+ linkaddr);
+#endif
+
+ strcpy(slideinfo[slideindex].linkinfo[linkindex].linkstring, linkaddr);
+
+ continue;
+ }
+
+ //not slide section, not hyperlink section, not display box section, then err
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right!");
+ return false;
+
+ }
+ }
+
+ return true;
+}
+
+
+//Resize and Rotate slides
+bool Step3_ResizeAndRotateSlideBMP(BMPConvOpt *pOption)
+{
+ bool bRet=true;
+ BMP pptBMP;
+
+ SetEasyBMPwarningsOff();//set warning message on
+
+ //set pic width and height
+ ScaleParam scale;
+
+ //picture number
+ #if defined(MOVIE_MERGE_on)
+ binhead.slidecount = pOption->mvSlideNumber;
+ #endif
+ int picNum = binhead.slidecount; //sizeof(pptSlidesBmp)/sizeof(char*);
+ //printf("\n\r has %d slides", picNum);
+
+ //resize all picture
+ int i;
+ for(i=0; i<picNum;++i) {
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ scale.dimension.width = pOption->width;
+ scale.dimension.height = pOption->height;
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ scale.dimension.width = pOption->ssWidth;
+ scale.dimension.height = pOption->ssHeight;
+ }
+ #endif
+ //printf("\n\r process %s before create object",pptSlidesBmp[i]);
+ if(!pptBMP.ReadFromFile(pptSlidesBmp[i])) {
+ fprintf(stderr, "Fail to open slide bit map file for operation!");
+ return false;
+ }
+ //printf("\n\r process %s before rescale",pptSlidesBmp[i]);
+ bRet &= Rescale(pptBMP, 'd', scale);
+ //printf("\n\r process %s before setbitdepth",pptSlidesBmp[i]);
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ bRet &= pptBMP.SetBitDepth(pOption->bitdepth);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ bRet &= pptBMP.SetBitDepth(pOption->ssBitdepth);
+ }
+ #endif
+
+ //printf("\n\r process %s before writefile",pptSlidesBmp[i]);
+ if(!pptBMP.WriteToFile(pptSlidesResizedBmp[i])) {
+ fprintf(stderr, "Fail to open file to write converted bitmap file!");
+ return false;
+ }
+
+ //Rotate BMP
+
+
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ bRet &= Rotate(pptSlidesResizedBmp[i], pptSlidesResizedBmp[i], pOption->rotateangle);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ bRet &= Rotate(pptSlidesResizedBmp[i], pptSlidesResizedBmp[i], pOption->ssRotateangle);
+ }
+ #endif
+#ifdef DEBUG_CONVBMPINFO
+ FILE *pBmpFile;
+ pBmpFile = fopen(pptSlidesResizedBmp[i], "rb");
+ if(!pBmpFile) {
+ fprintf(stderr, "\n\r fail to open");
+ exit(3);
+ }
+ BMPHeader bmpHead;
+ fread((char*)&bmpHead, 1, sizeof(BMPHeader), pBmpFile);
+ fclose(pBmpFile);
+
+ printf("\n\r============bmp header==============");
+ printf("\n\r bmp.type is %x", bmpHead.type);
+ printf("\n\r bmp.filesize is %d", bmpHead.fileSize);
+ printf("\n\r bmp.width is %d", bmpHead.width);
+ printf("\n\r bmp.height is %d", bmpHead.height);
+ printf("\n\r bmp.compressed is %d", bmpHead.compression);
+ printf("\n\r bmp.bitdepth is %d", bmpHead.bits);
+
+#endif
+
+ }
+
+ return bRet;
+}
+
+//create demo bin from above variables
+bool Step4_GenerateDemoBin(BMPConvOpt *pOption)
+{
+ FILE *pBMPfile, *pBinContentfile, *pDemoBin;
+ unsigned int offset;
+ unsigned int slideoffset[MAXSLIDESPERBIN];//store each slide offset in temp file
+ char buf[1024];//as read/write file buffer
+
+ //bin file tag 'ATML'
+ binhead.tag = (unsigned int)'L'<<24 | (unsigned int)'M'<<16 |
+ (unsigned int)'T'<<8 | (unsigned int) 'A';
+
+ //first open bincontentfile to store all parsed slide bmp file
+ pBinContentfile = fopen(pBinContent, "wb");
+ if(!pBinContentfile) {
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n Open file fail during creating bin!");
+ return false;
+ }
+
+ slideoffset[0] = 0; offset = 0;
+ //write all parsed slide bmp files into a bincontentfile
+ for(unsigned int i = 0; i<binhead.slidecount; ++i) {
+
+ //at start of each loop, offset is stored with end of position of bincontentfile
+ unsigned int startoffset = offset;
+
+ //slides index bigger than available bmp files
+ if(parsedslides[i]> sizeof(pptSlidesResizedBmp)/ sizeof(char *)) {
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n slide %u,i %u",parsedslides[i], i);
+ fprintf(stderr, "\n Script file and bmp file count is not consistent!");
+ return false;
+ }
+
+ #if !defined(MOVIE_MERGE_on)
+ pBMPfile = fopen(pptSlidesResizedBmp[parsedslides[i]], "rb");
+ #else
+ pBMPfile = fopen(pptSlidesResizedBmp[i], "rb");
+ #endif
+ if(!pBMPfile) {
+ fclose(pBinContentfile);
+ fclose(pBMPfile);
+ fprintf(stderr, "\n Open bmp file fail!");
+ return false;
+ }
+
+ //convert bmp file bitmap data format to meet sam3 lcd coordinate
+ if(pOption->reversebitmaporder){
+
+ struct stat filestat;
+ //////////////////////////
+ unsigned int width = 0;
+ unsigned int height = 0;
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ width = pOption->width;
+ height = pOption->height;
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ width = pOption->ssWidth;
+ height = pOption->ssHeight;
+ }
+ #endif
+ //default 270 rotate make the bmp look like column-aligned store
+ if(pOption->rotateangle % 180 == 0)
+ {
+ width = pOption->height;
+ height = pOption->width;
+ }
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ if(pOption->rotateangle % 180 == 0)
+ {
+ width = pOption->height;
+ height = pOption->width;
+ }
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ if(pOption->ssRotateangle % 180 == 0)
+ {
+ width = pOption->ssHeight;
+ height = pOption->ssWidth;
+ }
+ }
+ #endif
+ //////////////////////////
+ fstat(fileno(pBMPfile), &filestat);
+
+ //printf("\n\r filesize is %u", filestat.st_size);
+ char *bmpfilebuf = (char *)malloc(filestat.st_size+1024);
+ char *convbmpbuf = (char *)malloc(filestat.st_size+1024);
+
+ if(!bmpfilebuf || !convbmpbuf) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n malloc space for bmp file fail!");
+ return false;
+ }
+
+ size_t numread = fread(bmpfilebuf, 1, filestat.st_size, pBMPfile);
+ if(numread != filestat.st_size) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n Read bmp file length is not right!");
+ return false;
+ }
+ unsigned int bitmapoffset = ((BMPHeader *)bmpfilebuf)->offset;
+
+ unsigned int byteperpixel = ((BMPHeader *)bmpfilebuf)->bits;
+ if(byteperpixel != 8 && byteperpixel != 16 && byteperpixel !=24 ) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n Conversion of bitmap order of bit depth %u is not supported yet!", byteperpixel);
+ return false;
+ }
+ byteperpixel /= 8;
+
+ memcpy(convbmpbuf, bmpfilebuf, bitmapoffset);
+
+ //printf("\n\r Begin to convert %ubit bitmap data to meet sam3 lcd format!",byteperpixel*8);
+ //convert orignal bitmap data to sam3-ek LCD api coordinate format
+ unsigned int j,k,s;
+ for (j = 0, s=0; j < width; ++j) {
+
+ for (k = 0; k < height && j*k*byteperpixel < filestat.st_size; k++) {
+
+ *(convbmpbuf+bitmapoffset+s) = bmpfilebuf[ bitmapoffset + \
+ ((width -j - 1)*height + k)*byteperpixel];
+ if(byteperpixel == 2) {
+ *(convbmpbuf+bitmapoffset+s+1) = bmpfilebuf[ bitmapoffset + \
+ ((width -j - 1)*height + k)*byteperpixel+1];
+ }
+ if(byteperpixel == 3) {
+ *(convbmpbuf+bitmapoffset+s+2) = bmpfilebuf[ bitmapoffset + \
+ ((width -j - 1)*height + k)*byteperpixel+2];
+ }
+ s += byteperpixel;
+ }
+ //printf("\n\r j is %d",j);
+ }
+
+ //printf("\n\r End to convert %ubit bitmap data!",byteperpixel*8);
+
+ //check if right long data conversion
+ if(j != width || k != height) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n\r not all expected bitmap data converted!");
+ return false;
+ }
+
+ fwrite(convbmpbuf, 1, filestat.st_size, pBinContentfile);
+ offset += filestat.st_size;
+
+ free(convbmpbuf);
+ free(bmpfilebuf);
+ } else {
+ //directly write all bmp file into the tmp bincontent file
+ while(!feof(pBMPfile)) {
+ size_t numread = fread(buf, 1, 1024, pBMPfile);
+ fwrite(buf, 1, numread, pBinContentfile);
+ offset += numread;
+ }
+ }
+
+ //store this slide bmp file size
+ slideinfo[i].slidedatalength = offset - startoffset;
+ //printf("\n\r slide size is %u", slideinfo[i].slidedatalength);
+
+ //store offset for next slides
+ slideoffset[i+1]= offset;
+ //printf("\n\r offset is %d", offset);
+ fclose(pBMPfile);
+
+#ifdef DEBUG_DISPSECTION
+ printf("\n --Slide %u has %u display box", i+1, slideinfo[i].dispboxcount);
+ unsigned s;
+ for(s = 0; s < slideinfo[i].dispboxcount; ++s) {
+ printf("\n slide count is %d, botm %d, left %d, width %d, height %d",\
+ i+1, slideinfo[i].dispboxinfo[s].dispboxbottom, \
+ slideinfo[i].dispboxinfo[s].dispboxleft, \
+ slideinfo[i].dispboxinfo[s].dispboxwidth, \
+ slideinfo[i].dispboxinfo[s].dispboxheight);
+ }
+#endif
+
+ }
+ fclose(pBinContentfile);
+
+ //get header size
+ unsigned int headersize = sizeof(DemoBINHeader) + sizeof(SlideINFOHeader)* binhead.slidecount;
+
+ //set headersize field of DemoBINHeader
+ binhead.headersize = headersize;
+ //printf("\n\r headersize is %d", headersize);
+
+ //set file size field of DemoBINHeader
+ binhead.filesize = headersize + offset;//offset should be bincontent filesize now
+
+ //correct slide offset and then set them info information struct
+ for(unsigned int i = 0; i < binhead.slidecount; ++i) {
+ slideinfo[i].slideoffset = slideoffset[i] + headersize;
+}
+
+ pDemoBin = fopen(pAtmlDemoBin, "wb");
+ if(!pDemoBin) {
+ fclose(pDemoBin);
+ fprintf(stderr, "\n\r Open file fail during creating bin!");
+ return false;
+ }
+
+ #if !defined(MOVIE_MERGE_on)
+ fwrite(&binhead, 1, sizeof(DemoBINHeader), pDemoBin);
+ for(unsigned int i = 0; i < binhead.slidecount; ++i) {
+ fwrite(&slideinfo[i], 1, sizeof(SlideINFOHeader), pDemoBin);
+ }
+ #else
+ unsigned int tmpSlideCount = binhead.slidecount;
+ fwrite(&tmpSlideCount, 1, sizeof(unsigned int), pDemoBin);
+ #endif
+
+ //open pBinContentfile in read mode for writing final demo bin
+ pBinContentfile = fopen(pBinContent, "rb");
+ if(!pBinContentfile) {
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n\r Open file fail during creating bin!");
+ return false;
+ }
+
+ //write the slide bin file to final demo bin
+ while(!feof(pBinContentfile)) {
+ size_t numread = fread(buf, 1, 1024, pBinContentfile);
+ fwrite(buf, 1, numread, pDemoBin);
+ }
+
+ fclose(pBinContentfile);
+ fclose(pDemoBin);
+
+ //remove temporary bincontentfile
+ if(remove(pBinContent))
+ fprintf(stderr, "\n\r Can't remove temporary file!");
+
+ return true;
+}
+
+//show generated bin contained bmp information
+void ShowEachBmpHeader()
+{
+ FILE *pBinfile;
+ DemoBINHeader binheader;
+ SlideINFOHeader slideinfo;
+ BMPHeader bmphead;
+
+ pBinfile = fopen(pAtmlDemoBin, "rb");
+ if(!pBinfile) {
+ fprintf(stderr, "\n\r Fail to open demo bin file!!");
+ return;
+ }
+
+ fread(&binheader, 1, sizeof(DemoBINHeader),pBinfile);
+ unsigned int slidecount = binheader.slidecount;
+ printf("\n\r Demo bin has %u slides", slidecount);
+
+ for(unsigned int j=0; j < slidecount;++j) {
+ fseek(pBinfile, sizeof(DemoBINHeader) + j *sizeof(SlideINFOHeader), SEEK_SET);
+ fread(&slideinfo, 1, sizeof(SlideINFOHeader), pBinfile);
+ printf("\n\r slide %d bitdata in %u,length %u",j, slideinfo.slideoffset, slideinfo.slidedatalength);
+ fseek(pBinfile, slideinfo.slideoffset, SEEK_SET);
+ fread(&bmphead, 1, sizeof(BMPHeader), pBinfile);
+ printf("\n\r============bmp header==============");
+ printf("\n\r bmp.type is %x", bmphead.type);
+ printf("\n\r bmp.filesize is %d", bmphead.fileSize);
+ printf("\n\r bmp.width is %d", bmphead.width);
+ printf("\n\r bmp.height is %d", bmphead.height);
+ printf("\n\r bmp.compressed is %d", bmphead.compression);
+ printf("\n\r bmp.bitdepth is %d", bmphead.bits);
+
+ }
+
+ fclose(pBinfile);
+}
+
personal git repositories of Harald Welte. Your mileage may vary