Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

extract BMP images from APP or EXE files 3

Status
Not open for further replies.

Olaf Doschke

Programmer
Oct 13, 2004
14,847
DE
I had a case of lost BMP images from a project folder, but got an APP file including the images. This code detects BMP files by it's simply header "BM" followed by size of the file in 2 bytes.

Code:
#Define ccVFPApp "C:\...\your.exe"
#Define ccImageFolder "C:\extractedBMPs\"

Local lcVFPApp, lnBMPPosition, lcBMPHeader, i

i=1
Do While .T.
   lnBMPPosition = At("BM",lcVFPApp,i)
   If lnBMPPosition=0
      Exit
   Endif

   lcBMPHeader = Substr(lcVFPApp,lnBMPPosition ,4)
   lnSize = CToBin(Right(lcBMPHeader,2),"2RS")

   If lnSize<=4
      * wrong size, surely not a bmp
   Else
      lcFilename = "image"+PADL(i,3,"0")+".bmp"
      StrToFile(Substr(lcVFPApp,lnBMPPosition ,lnSize),Addbs(ccImageFolder)+lcFilename)
   Endif

   i = i + 1
EndDo

Maybe it'll help some other poor soul with the same problem. If you know the inner file structure of GIF, JPG, PNG, etc. you'd be able to find and extract them, too. In my case BMP was just fine.

Bye, Olaf.
 
Thanks for the information about the GIF.
I still believe it can be improved, because in some of my own tests I got wrong results.
The obvious approach is to spend some time and read the documentations about GIFs (in fact this is what I did for BMP, PNG and JPG).

Anyway, it is fun doing that [smile]

It's not the first time when I was interested about this subject.
A little while ago I created some functions for checking if a file is a picture with some maximum dimensions.

And before VFP9 I was interested to create some BMPs to display text vertically (in VFP9 the labels had the rotation property) and so I studied the specifications for BMP.
Also I used that class to create gradient filled rectangles.

Next I posted the code for is_pic and later a class for generating BMPs. (demo for 12x12 up arrow and down arrow).
The genBmp method can be used to generate any BMP file (genBMP expose the structure of a BMP).
Just create your own bitmap method (similar with UpArrow or DownArrow) and call them from genBMP
To understand the UpArrow method, must be said that each bitmap is a string of triplets of bytes (RGB code) from bottom to up. Each row should be a multiple of 4


Code:
******************************************************************
*  Check if a file is a bmp , gif , jpg or png
* Optional width and height of the image is compared with maximum values .
******************************************************************
* Return value is
* 0 - success
* 1 - none of the accepted type
* 2 - too wide
* 4 - too high
******************************************************************
* is_pic can be called with 1-3 parameters:
* - image file
* - maximum width
* - maximum height
******************************************************************
FUNCTION is_pic
LPARAMETERS lcFil,lnwidthm,lnheightm
LOCAL llIspict
llIspict=is_png(m.lcFil,m.lnwidthm,m.lnheightm)
IF m.llIspict!=1
  RETURN m.llIspict
ELSE
  llIspict=is_gif(m.lcFil,m.lnwidthm,m.lnheightm)
  IF m.llIspict!=1
    RETURN m.llIspict
  ELSE
    llIspict=is_bmp(m.lcFil,m.lnwidthm,m.lnheightm)
    IF m.llIspict!=1
      RETURN m.llIspict
    ELSE
      llIspict=is_jpg(m.lcFil,m.lnwidthm,m.lnheightm)
      RETURN llIspict
    ENDIF
  ENDIF
ENDIF
******************************************************************
*  Check if a file is a bmp
* Optional width and height of the image is compared with maximum values .
******************************************************************
* Return value is
* 0 - success
* 1 - not a BMP
* 2 - too wide
* 4 - too high
******************************************************************
* is_bmp can be called with 1-3 parameters:
* - image file
* - maximum width
* - maximum height
******************************************************************
FUNCTION is_bmp
LPARAMETERS lcFil,lnwidthm,lnheightm
LOCAL lcS,llSgn,lnWidth,lnHeight,llIsbmp,llIsWidth,llIsHeight
llIsbmp=0
llIsWidth=PCOUNT()>1 and VARTYPE(m.lnwidthm)="N"
IF m.llIsWidth
  llIsWidth=m.lnwidthm>0
ENDIF
llIsHeight=PCOUNT()>1 and VARTYPE(m.lnheightm)="N"
IF m.llIsHeight
  llIsHeight=m.lnheightm>0
ENDIF
lcs=FILETOSTR(FULLPATH(m.lcfil))
llsgn=ASC(SUBSTR(m.lcs,1,1))=66 and ASC(SUBSTR(m.lcs,2,1))=77
IF m.llsgn
  lnwidth=ASC(SUBSTR(m.lcs,17))*256*256+ASC(SUBSTR(m.lcs,18))*256*256*256+ASC(SUBSTR(m.lcs,19))+ASC(SUBSTR(m.lcs,20))*256
  IF m.llIsWidth
    IF m.lnwidth>m.lnwidthm
      llIsbmp=m.llIsbmp+2
    ENDIF
  ENDIF
  lnheight=ASC(SUBSTR(m.lcs,21))*256*256+ASC(SUBSTR(m.lcs,22))*256*256*256+ASC(SUBSTR(m.lcs,23))+ASC(SUBSTR(m.lcs,24))*256
  IF m.llIsHeight
    IF m.lnheight>m.lnheightm
      llIsbmp=m.llIsbmp+4
    ENDIF
  ENDIF
ELSE
  llIsbmp=m.llIsbmp+1
ENDIF
RETURN m.llIsbmp
******************************************************************
*  Check if a file is png
* Optional width and height of the image is compared with maximum values .
******************************************************************
* Return value is
* 0 - success
* 1 - not a PNG
* 2 - too wide
* 4 - too high
******************************************************************
* is_png can be called with 1-3 parameters:
* - image file
* - maximum width
* - maximum height
******************************************************************
FUNCTION is_png
LPARAMETERS lcFil,lnwidthm,lnheightm
LOCAL lcS,llSgn,lnWidth,lnHeight,llIspng,llIsWidth,llIsHeight
llIspng=0
llIsWidth=PCOUNT()>1 and VARTYPE(m.lnwidthm)="N"
IF m.llIsWidth
  llIsWidth=m.lnwidthm>0
ENDIF
llIsHeight=PCOUNT()>1 and VARTYPE(m.lnheightm)="N"
IF m.llIsHeight
  llIsHeight=m.lnheightm>0
ENDIF
lcs=FILETOSTR(FULLPATH(m.lcfil))
llsgn=ASC(SUBSTR(m.lcs,1,1))=137 and ASC(SUBSTR(m.lcs,2,1))=80 and ASC(SUBSTR(m.lcs,3,1))=78 and ASC(SUBSTR(m.lcs,4,1))=71 and ASC(SUBSTR(m.lcs,5,1))=13 and ASC(SUBSTR(m.lcs,6,1))=10 and ASC(SUBSTR(m.lcs,7,1))=26 and ASC(SUBSTR(m.lcs,8,1))=10
IF m.llsgn
  lnwidth=ASC(SUBSTR(m.lcs,17))*256*256*256+ASC(SUBSTR(m.lcs,18))*256*256+ASC(SUBSTR(m.lcs,19))*256+ASC(SUBSTR(m.lcs,20))
  IF m.llIsWidth
    IF m.lnwidth>m.lnwidthm
      llIspng=m.llIspng+2
    ENDIF
  ENDIF
  lnheight=ASC(SUBSTR(m.lcs,21))*256*256*256+ASC(SUBSTR(m.lcs,22))*256*256+ASC(SUBSTR(m.lcs,23))*256+ASC(SUBSTR(m.lcs,24))
  IF m.llIsHeight
    IF m.lnheight>m.lnheightm
      llIspng=m.llIspng+4
    ENDIF
  ENDIF
ELSE
  llIspng=m.llIspng+1
ENDIF
RETURN m.llIspng
******************************************************************
*  Check if a file is a gif
* Optional width and height of the image is compared with maximum values .
******************************************************************
* Return value is
* 0 - success
* 1 - not a GIF
* 2 - too wide
* 4 - too high
******************************************************************
* is_gif can be called with 1-3 parameters:
* - image file
* - maximum width
* - maximum height
******************************************************************
FUNCTION is_gif
LPARAMETERS lcFil,lnwidthm,lnheightm
LOCAL lcS,llSgn,lnWidth,lnHeight,llIsgif,llIsWidth,llIsHeight
llIsgif=0
llIsWidth=PCOUNT()>1 and VARTYPE(m.lnwidthm)="N"
IF m.llIsWidth
  llIsWidth=m.lnwidthm>0
ENDIF
llIsHeight=PCOUNT()>1 and VARTYPE(m.lnheightm)="N"
IF m.llIsHeight
  llIsHeight=m.lnheightm>0
ENDIF
lcs=FILETOSTR(FULLPATH(m.lcfil))
llsgn=ASC(SUBSTR(m.lcs,1,1))=71 and ASC(SUBSTR(m.lcs,2,1))=73 and ASC(SUBSTR(m.lcs,3,1))=70
IF m.llsgn
  lnwidth=ASC(SUBSTR(m.lcs,7))+ASC(SUBSTR(m.lcs,8))*256
  IF m.llIsWidth
    IF m.lnwidth>m.lnwidthm
      llIsgif=m.llIsgif+2
    ENDIF
  ENDIF
  lnheight=ASC(SUBSTR(m.lcs,9))+ASC(SUBSTR(m.lcs,10))*256
  IF m.llIsHeight
    IF m.lnheight>m.lnheightm
      llIsgif=m.llIsgif+4
    ENDIF
  ENDIF
ELSE
  llIsgif=m.llIsgif+1
ENDIF
RETURN m.llIsgif
******************************************************************
*  Check if a file is a jpg
* Optional width and height of the image is compared with maximum values .
******************************************************************
* Return value is
* 0 - success
* 1 - not a JPG
* 2 - too wide
* 4 - too high
******************************************************************
* is_jpg can be called with 1-3 parameters:
* - image file
* - maximum width
* - maximum height
******************************************************************
FUNCTION is_jpg
LPARAMETERS lcFil,lnwidthm,lnheightm
LOCAL lcS,llSgn,lnWidth,lnHeight,llIsjpg,lnstart,lni,llIsWidth,llIsHeight
llIsjpg=0
llIsWidth=PCOUNT()>1 and VARTYPE(m.lnwidthm)="N"
IF m.llIsWidth
  llIsWidth=m.lnwidthm>0
ENDIF
llIsHeight=PCOUNT()>1 and VARTYPE(m.lnheightm)="N"
IF m.llIsHeight
  llIsHeight=m.lnheightm>0
ENDIF
lcs=FILETOSTR(FULLPATH(m.lcfil))
llsgn=.F.
STORE 0 TO m.lnwidth,m.lnheight
FOR lni=1 TO LEN(m.lcs)-2
  IF ASC(SUBSTR(m.lcs,m.lni,1))=255 and ASC(SUBSTR(m.lcs,m.lni+1,1))=216 and ASC(SUBSTR(m.lcs,m.lni+2,1))=255
    llsgn=.T.
    lnstart=m.lni+2
    EXIT
  ENDIF
NEXT
IF m.llsgn
  lni=m.lnstart
  DO WHILE m.lni<LEN(m.lcs)
    IF ASC(SUBSTR(m.lcs,m.lni,1))=255 and ASC(SUBSTR(m.lcs,m.lni+1,1))!=255 
      IF INLIST(ASC(SUBSTR(m.lcs,m.lni+1,1)),0xC0,0xC1,0xC2,0xC3,0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF)
        lnwidth=ASC(SUBSTR(m.lcs,m.lni+6))+ASC(SUBSTR(m.lcs,m.lni+5))*256
        IF m.llIsWidth
          IF m.lnwidth>m.lnwidthm
            llIsjpg=m.llIsjpg+2
          ENDIF
        ENDIF
        lnheight=ASC(SUBSTR(m.lcs,m.lni+8))+ASC(SUBSTR(m.lcs,m.lni+7))*256
        IF m.llIsHeight
          IF m.lnheight>m.lnheightm
            llIsjpg=m.llIsjpg+4
          ENDIF
        ENDIF
        EXIT
      ELSE
        lni=m.lni+1+ASC(SUBSTR(m.lcs,m.lni+3))+ASC(SUBSTR(m.lcs,m.lni+2))*256
        LOOP
      ENDIF
    ENDIF
    lni=m.lni+1
  ENDDO
ELSE
  llIsjpg=m.llIsjpg+1
ENDIF
RETURN m.llIsjpg

The BMP generator class
Code:
*****************************
*****************************
* Generating the Arrows
*****************************
DEFINE CLASS GenBmp as custom
	cFileName=''
	nWhat=1
	nLevel=2
****************************
* Bitmap low level file generator
****************************
	PROCEDURE genBmp
		LOCAL lni,lcS,lnLength,lcSa,lnNumber,lnSize
		This.cFileName=FORCEEXT(This.cFileName,"bmp")
		DO CASE
		CASE This.nWhat=1
			lcS=This.UpArrow()
		CASE This.nWhat=2
			lcS=This.DownArrow()
		ENDCASE
		lnLength=LEN(lcS)
		lnSize=12 && 12x12 bitmap
	* Header
	* bitmap signature: BM (CHR(0x42)+CHR(0x4D))
		lcSa=CHR(0x42)+CHR(0x4D)
	* File length 
		lnNumber=This.DecTohex(m.lnLength+56)
		lcSa=m.lcSa+m.lnNumber
		FOR lni=1 TO 8-LEN(m.lnNumber)
			lcSa=m.lcSa+CHR(0)
		NEXT
	*CHR(0x36)=3*16+6=56=file header length
	*CHR(0x28)=2*16+8=40=next structure length
		lcSa=m.lcSa+CHR(0x36)+CHR(0)+CHR(0)+CHR(0)+CHR(0x28)+CHR(0)+CHR(0)+CHR(0)
	* Width and Height in pixels
	* width
		lnNumber=This.DecTohex(m.lnSize) &&(lnLength/lnSize-2)/3
		lcSa=m.lcSa+m.lnNumber
		FOR lni=1 TO 4-LEN(m.lnNumber)
			lcSa=m.lcSa+CHR(0)
		NEXT
	* height
		lnNumber=This.DecTohex(m.lnSize)
		lcSa=m.lcSa+m.lnNumber && +CHR(0x0C)+CHR(0)+CHR(0)+CHR(0) 
		FOR lni=1 TO 4-LEN(m.lnNumber)
			lcSa=m.lcSa+CHR(0)
		NEXT
	* layers, 1
		lcSa=m.lcSa+CHR(0x1)+CHR(0)
	* Color depth: 1,4,8 or 24 (0x18) bits
		lcSa=m.lcSa+CHR(0x18)+CHR(0)
	* compression
		lcSa=m.lcSa+CHR(0)+CHR(0)+CHR(0)+CHR(0)
	*  image length
		lnNumber=This.DecTohex(m.lnLength)
		lcSa=m.lcSa+m.lnNumber
		FOR lni=1 TO 8-LEN(m.lnNumber)
			lcSa=m.lcSa+CHR(0)
		NEXT
	* horizontal resolution
		lcSa=m.lcSa+CHR(0)+CHR(0)+CHR(0)+CHR(0)
	* vertical resolution
		lcSa=m.lcSa+CHR(0)+CHR(0)+CHR(0)+CHR(0)
	* 0=> entire palette
		lcSa=m.lcSa+CHR(0)+CHR(0)
	* 0=> all colors matters
		lcSa=m.lcSa+CHR(0)+CHR(0)
		lcS=m.lcSa+m.lcS
		STRTOFILE(m.lcS,This.cFileName)
		RETURN This.cFileName
	ENDPROC

****************************
* 12x12 Bitmap definition for down arrow
****************************
	PROCEDURE DownArrow
		LOCAL lcS,lni,lcGray,lcBlack,lcWhite,lnSize
		lnSize=12
		lcGray=CHR(255-CEILING(256/This.nLevel)+1)+CHR(CEILING(256/This.nLevel)-1)+CHR(255)
		lcBlack=CHR(0)+CHR(0)+CHR(0)
		lcWhite=CHR(255)+CHR(255)+CHR(255)
		lcS=''
		* 1
		FOR lni=1 TO m.lnSize
			lcS=m.lcS+m.lcWhite
		NEXT
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 2
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 3
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 4
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcBlack+m.lcBlack+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 5
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 6
		lcS=m.lcS+m.lcWhite+m.lcGray
		FOR lni=1 TO 8
			lcS=m.lcS+m.lcBlack
		NEXT
		lcS=m.lcS+m.lcGray+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 7
		lcS=m.lcS+m.lcWhite+m.lcGray+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcGray+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 8,9
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 10
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray
		FOR lni=1 TO 4
			lcS=m.lcS+m.lcBlack
		NEXT
		lcS=m.lcS+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 11
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO 6
			lcS=m.lcS+m.lcGray
		NEXT
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 12
		FOR lni=1 TO m.lnSize
			lcS=m.lcS+m.lcWhite
		NEXT
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
	RETURN lcS


****************************
* 12x12 Bitmap definition for up arrow
****************************
	PROCEDURE UpArrow
		LOCAL lcS,lni,lcGray,lcBlack,lcWhite,lnSize
		lnSize=12
		lcGray=CHR(255-CEILING(256/This.nLevel)+1)+CHR(CEILING(256/This.nLevel)-1)+CHR(255)
		lcBlack=CHR(0)+CHR(0)+CHR(0)
		lcWhite=CHR(255)+CHR(255)+CHR(255)
		lcS=''
		* 1
		FOR lni=1 TO m.lnSize
			lcS=m.lcS+m.lcWhite
		NEXT
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 2
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO 6
			lcS=m.lcS+m.lcGray
		NEXT
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 3
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray
		FOR lni=1 TO 4
			lcS=m.lcS+m.lcBlack
		NEXT
		lcS=m.lcS+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 4,5
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 6
		lcS=m.lcS+m.lcWhite+m.lcGray+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcGray+m.lcGray+m.lcGray+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 7
		lcS=m.lcS+m.lcWhite+m.lcGray
		FOR lni=1 TO 8
			lcS=m.lcS+m.lcBlack
		NEXT
		lcS=m.lcS+m.lcGray+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 8
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcBlack+m.lcGray+m.lcGray+m.lcBlack+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 9
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcBlack+m.lcBlack+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 10
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcBlack+m.lcBlack+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 11
		lcS=m.lcS+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcGray+m.lcGray+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite+m.lcWhite
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
		* 12
		FOR lni=1 TO m.lnSize
			lcS=m.lcS+m.lcWhite
		NEXT
		FOR lni=1 TO MOD(m.lnSize,4)
			lcS=m.lcS+CHR(0)
		NEXT
	RETURN lcS

****************************
	PROCEDURE DecTohex
		LPARAMETERS lnNo
		LOCAL lcS,lnC,lnI,lnF,lnSign,lnDigit
		lnSign=SIGN(m.lnNo)
		lnNo=ABS(m.lnNo)
		lnI=FLOOR(m.lnNo)
		lnF=m.lnNo-m.lnI
		lcS=''
		DO WHILE m.lnI!=0
			lnC=MOD(m.lnI,256)
			lcS=m.lcS+CHR(m.lnC)
			lnI=FLOOR(m.lnI/256)
		ENDDO
		IF LEN(m.lcS)=0 && 0
			lcS=CHR(0)
		ENDIF
	RETURN m.lcS
ENDDEFINE

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Olaf,

I have prepared an article which incorporates your code. If you would like to review it before it goes public, contact me privately and I will send you a link. (You can contact me via my website, as per my signature.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
For those who are interested in this topic, I have now published Olaf's article, which includes the code he shows here. The code in the article has been beautified, but the functionality is the same. The article is at
Vilhelm-Ion: I didn't mean to ignore your variations of the code. If you'd like me to publish something similar - perhaps with a single consolidated routine for the different file types - I'd be happy to do so.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Vilhelm-Ion, I already suggested your extended versions could be put as answer to this article, if HexCentral works this way (allowing comments/answers), but of course a follow up article would be a good idea, too.

Thanks again. It shows you actually don't need much time and effort. But knowing me I would have been much more elaborate and never satisfied with the result. This short article is fine and up to the point. I mainly need to learn how to focus on the core point.

Bye, Olaf.
 
Good article.

First I must improve the GIF detection, as I promised.
I remember a Rolling Stones hit "Time is on my side" [smile]


Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
I'm looking forward to that, Vilhelm-Ion.

Mike, I spot another issue right now. As you left out the #DEFINE, the code references an undefined ccVFPApp constant. That's not so easy to spot, as I don't follow the convention of writing constant names all upper case, but use a c (as constant) prefix, extending the usual naming conventions for variables.

ccVFPApp is just a fallback or default value in case the parameter tcVFPApp is not passed in, so you could simply remove the line tcVFPApp = EVL(tcVFPApp, ccVFPApp).

Bye, Olaf.
 
I'll try to overcome my laziness and provide a better GIF extractor.
The problem is that some GIF's contains the EOF marker chr(0)+';' inside them (somehow similar with the problem found in JPG)

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Olaf said:
I spot another issue right now. As you left out the #DEFINE, the code references an undefined ccVFPApp constant.

Well spotted, Olaf. (And it's a bit ironic, considering I pointed out a similar issue in my first post in this thread.)

Anyway, I've made the change, as you suggested. I also removed this line:
[tt]
tcDestinationImageFolder = EVL(tcDestinationImageFolder, ccImageFolder)[/tt]

which has the same problem. I didn't notice this in my testing, because I only ever called the function with the correct number of parameters.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks, Mike.

Yes, that's the forgiveness of the compiler, the names of the constants could be names of a field, which would be read in that case, therefore many things like that compile and wold only error at runtime, if they are really executed/read, and EVL only cares for the second parameter/expression, if the first one is empty.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top