DEFINE VARIABLE vImage AS System.Drawing.Image NO-UNDO.
vImage = System.Drawing.Image:FromFile("s:\imagens_web\1010150005000528_web.jpg") .
MESSAGE "Width: " + string(vImage:Width) + ", Height: " + string(vImage:Height)
VIEW-AS ALERT-BOX INFO BUTTONS OK.
vImage:Dispose().
FUNCTION progress_jpeg RETURNS INTEGER EXTENT 2 (INPUT imageData AS MEMPTR):
DEFINE VARIABLE in_offset AS INTEGER NO-UNDO.
DEFINE VARIABLE in_marker AS INTEGER NO-UNDO.
DEFINE VARIABLE in_length AS INTEGER NO-UNDO.
DEFINE VARIABLE in_FileSize AS INTEGER NO-UNDO.
DEFINE VARIABLE in_ImageDimensions AS INTEGER NO-UNDO INITIAL ? EXTENT 2 .
/* JPEG files are all big-endian byte order.*/
SET-BYTE-ORDER(imageData) = BIG-ENDIAN.
MESSAGE 'JPEG'.
in_offset = 3. /** Ignore the first two bytes.**/
in_FileSize = GET-SIZE(ImageData).
Byte-Scan:
DO WHILE in_offset LT in_FileSize:
in_marker = GET-UNSIGNED-SHORT(ImageData,in_offset).
in_length = GET-UNSIGNED-SHORT(ImageData,in_offset + 2).
IF (in_marker EQ 0xFFC0 OR in_marker EQ 0xFFC2) THEN
DO:
ASSIGN
in_ImageDimensions[2] = GET-UNSIGNED-SHORT(ImageData,in_offset + 5) /** Width **/
in_ImageDimensions[1] = GET-UNSIGNED-SHORT(ImageData,in_offset + 7). /** Height **/
LEAVE Byte-Scan.
END.
in_offset = in_offset + in_length + 2.
END.
RETURN in_ImageDimensions.
END FUNCTION.
FUNCTION progress_png RETURNS INTEGER EXTENT 2 (INPUT imageData AS MEMPTR):
DEFINE VARIABLE in_ImageDimensions AS INTEGER NO-UNDO EXTENT 2 INITIAL ?.
MESSAGE 'PNG'.
/* PNG file are in network byte order (big-endian) */
SET-BYTE-ORDER(imageData) = BIG-ENDIAN.
ASSIGN
in_ImageDimensions[1] = GET-UNSIGNED-LONG(imageData,17) /** Width **/
in_ImageDimensions[2] = GET-UNSIGNED-LONG(imageData,21). /** Height **/
SET-SIZE(imageData) = 0 .
RETURN in_ImageDimensions.
END FUNCTION.
FUNCTION progress_bmp RETURNS INTEGER EXTENT 2 (INPUT imageData AS MEMPTR):
DEFINE VARIABLE in_ImageDimensions AS INTEGER NO-UNDO EXTENT 2 INITIAL ?.
/** All of the integer values are stored in little-endian format (i.e. least-significant byte first). **/
SET-BYTE-ORDER(imageData) = LITTLE-ENDIAN.
MESSAGE 'BMP'.
ASSIGN
in_ImageDimensions[1] = GET-UNSIGNED-LONG(imageData,19) /** Width **/
in_ImageDimensions[2] = GET-UNSIGNED-LONG(imageData,23). /** Height **/
SET-SIZE(imageData) = 0 .
RETURN in_ImageDimensions.
END FUNCTION.
FUNCTION progress_gif RETURNS INTEGER EXTENT 2 (INPUT imageData AS MEMPTR):
DEFINE VARIABLE in_ImageDimensions AS INTEGER EXTENT 2 NO-UNDO.
/** All of the integer values are stored in little-endian format (i.e. least-significant byte first). **/
SET-BYTE-ORDER(imageData) = LITTLE-ENDIAN.
MESSAGE 'GIF'.
ASSIGN
in_ImageDimensions[1] = GET-SHORT(imageData,7) /** Width **/
in_ImageDimensions[2] = GET-SHORT(imageData,9). /** Height **/
SET-SIZE(imageData) = 0 .
RETURN in_ImageDimensions.
END FUNCTION.
FUNCTION GetImageDimensions RETURNS INTEGER EXTENT 2 (INPUT ch_filename AS CHARACTER):
DEFINE VARIABLE imageData AS MEMPTR NO-UNDO.
DEFINE VARIABLE in_ImageDimensions AS INTEGER NO-UNDO EXTENT 2 INITIAL ?.
DEFINE VARIABLE rPNGSignature AS RAW NO-UNDO.
DEFINE VARIABLE rBMPSignature AS RAW NO-UNDO.
DEFINE VARIABLE rGIFSIGNATURE AS RAW NO-UNDO.
DEFINE VARIABLE rJPEGSignature AS RAW NO-UNDO.
rPNGSignature = HEX-DECODE('89504E470D0A1A0A':U).
rBMPSignature = HEX-DECODE('424D':U).
rGIFSignature = HEX-DECODE('47494638':U).
rJPEGSignature = HEX-DECODE('FFD8FF':U).
ch_filename = SEARCH(ch_filename).
IF ch_filename EQ ? THEN
RETURN in_ImageDimensions.
SET-SIZE(imageData) = 0. /** Always reset your MEMPTRs **/
COPY-LOB FROM FILE ch_filename TO OBJECT imageData.
/************************************/
/* DEBUG CODE ***********************/
/************************************/
/* DEFINE VARIABLE iBYTE AS INTEGER NO-UNDO. */
/* DEFINE VARIABLE imageRAW AS RAW NO-UNDO. */
/* */
/* OUTPUT STREAM sDebug TO 'hex-encoded.txt'. */
/* */
/* DO iBYTE = 1 TO GET-SIZE(ImageData): */
/* imagERAW= GET-BYTES(ImageData,iBYTE,1). */
/* PUT STREAM sDebug UNFORMATTED TRIM(STRING(HEX-ENCODE(imagERAW))) + ' '. */
/* IF iBYTE MOD 16 EQ 0 THEN */
/* PUT STREAM sDebug SKIP. */
/* END. */
/* OUTPUT STREAM sDebug CLOSE. */
/** Magic Number for File Tpye Identification..**/
CASE TRUE:
WHEN GET-BYTES(imageData,1,3) EQ rJPEGSignature THEN /** JPEG **/
in_ImageDimensions = progress_jpeg(INPUT imageData ).
WHEN GET-BYTES(imageData,1,8) EQ rPNGSignature THEN /** PNG **/
in_ImageDimensions = progress_png(INPUT imageData ).
WHEN GET-BYTES(imageData,1,2) EQ rBMPSignature THEN /** BMP **/
in_ImageDimensions = progress_bmp(INPUT imageData ).
WHEN GET-BYTES(imageData,1,4) EQ rGIFSignature THEN /** GIF **/
in_ImageDimensions = progress_gif(INPUT imageData ).
END CASE.
SET-SIZE(imageData) = 0. /** Always reset your MEMPTRs **/
RETURN in_ImageDimensions.
END FUNCTION.
DEFINE STREAM sDebug.
DEFINE VARIABLE in_ImageDimensions AS INTEGER NO-UNDO EXTENT 2 INITIAL ?.
in_ImageDimensions = GetImageDimensions(INPUT "webspeed\images\pscpbp1.gif").
/* in_ImageDimensions = GetImageDimensions(INPUT "webspeed\samples\internet\cat00029.jpg"). */
/* in_ImageDimensions = GetImageDimentions(INPUT "netsetup\setup.bmp"). */
/* in_ImageDimensions = GetImageDimentions(INPUT "jdk\jre\lib\servicetag\jdk_header.png"). */
MESSAGE 'Width' in_ImageDimensions[1] SKIP
'Height' in_ImageDimensions[2]
VIEW-AS ALERT-BOX INFO.
METHOD STATIC PUBLIC VOID getPictureInfo (
pImage AS CHARACTER
,OUTPUT opcType AS CHARACTER
,OUTPUT opiWidth AS INTEGER
,OUTPUT opiHeight AS INTEGER):
DEFINE VARIABLE mImage AS MEMPTR NO-UNDO.
DEFINE VARIABLE iPos AS INTEGER NO-UNDO.
DEFINE VARIABLE lSkip AS LOGICAL NO-UNDO.
SET-SIZE(mImage) = 32.
INPUT FROM VALUE(SEARCH(pImage)) BINARY NO-MAP NO-CONVERT NO-ECHO.
IMPORT mImage.
INPUT CLOSE.
IF GET-BYTE(mImage, 1) = 137
AND GET-BYTES(mImage, 2, 3) = "PNG"
AND GET-BYTE(mImage, 5) = 13 AND GET-BYTE(mImage, 6) = 10
AND GET-BYTE(mImage, 7) = 26 AND GET-BYTE(mImage, 8) = 10 THEN DO:
ASSIGN
opcType = "image/png"
opiWidth = 16777216 * GET-BYTE(mImage, 17) + 65536 * GET-BYTE(mImage, 18) + 256 * GET-BYTE(mImage, 19) + GET-BYTE(mImage, 20)
opiHeight = 16777216 * GET-BYTE(mImage, 21) + 65536 * GET-BYTE(mImage, 22) + 256 * GET-BYTE(mImage, 23) + GET-BYTE(mImage, 24).
END. /* PNG */
&GLOBAL-DEFINE M_SOF0 192 /* 0xC0 */ /* Start Of Frame N */
&GLOBAL-DEFINE M_SOF1 193 /* 0xC1 */ /* N indicates which compression process */
&GLOBAL-DEFINE M_SOF2 194 /* 0xC2 */ /* Only SOF0-SOF2 are now in common use */
&GLOBAL-DEFINE M_SOF3 195 /* 0xC3 */
&GLOBAL-DEFINE M_SOF5 197 /* 0xC5 */ /* NB: codes C4 and CC are NOT SOF markers */
&GLOBAL-DEFINE M_SOF6 198 /* 0xC6 */
&GLOBAL-DEFINE M_SOF7 199 /* 0xC7 */
&GLOBAL-DEFINE M_SOF9 201 /* 0xC9 */
&GLOBAL-DEFINE M_SOF10 202 /* 0xCA */
&GLOBAL-DEFINE M_SOF11 203 /* 0xCB */
&GLOBAL-DEFINE M_SOF13 205 /* 0xCD */
&GLOBAL-DEFINE M_SOF14 206 /* 0xCE */
&GLOBAL-DEFINE M_SOF15 207 /* 0xCF */
&GLOBAL-DEFINE M_SOI 216 /* 0xD8 */ /* Start Of Image (beginning of datastream) */
&GLOBAL-DEFINE M_EOI 217 /* 0xD9 */ /* End Of Image (end of datastream) */
&GLOBAL-DEFINE M_SOS 218 /* 0xDA */ /* Start Of Scan (begins compressed data) */
&GLOBAL-DEFINE M_APP0 224 /* 0xE0 */ /* Application-specific marker, type N */
&GLOBAL-DEFINE M_APP12 236 /* 0xEC */ /* (we don't bother to list all 16 APPn's) */
&GLOBAL-DEFINE M_APP14 238 /* 0xEE */ /* 13-NOV-2013 jcc: add Adobe APP14 support for CMYK files */
&GLOBAL-DEFINE M_COM 254 /* 0xFE */ /* Comment */
&GLOBAL-DEFINE M_MARK 255 /* 0xFF */ /* Marker */
ELSE IF GET-BYTE(mImage, 1) = {&M_MARK}
AND GET-BYTE(mImage, 2) = {&M_SOI} THEN DO: /* might be JPG */
SET-SIZE(mImage) = 0.
COPY-LOB FILE pImage TO mImage.
iPos = 3.
blkMarkers:
DO WHILE TRUE:
/* loop through the markers until we find the one starting with 0xFF,0xC0
which is the block containing the image information */
DO WHILE TRUE: /* loop until we find the beginning of the next marker */
IF GET-BYTE(mImage, iPos) = {&M_Mark}
AND GET-BYTE(mImage, iPos + 1) <> {&M_Mark} THEN
LEAVE.
iPos = iPos + 1.
IF iPos >= GET-SIZE(mImage) - 10 THEN DO:
SET-SIZE(mImage) = 0.
RETURN.
END.
END.
ASSIGN
lSkip = NO
iPos = iPos + 1.
CASE GET-BYTE(mImage, iPos):
WHEN {&M_SOF0} OR WHEN {&M_SOF1} OR WHEN {&M_SOF2} OR WHEN {&M_SOF3}
OR WHEN {&M_SOF5} OR WHEN {&M_SOF6} OR WHEN {&M_SOF7} OR WHEN {&M_SOF9}
OR WHEN {&M_SOF10} OR WHEN {&M_SOF11} OR WHEN {&M_SOF13}
OR WHEN {&M_SOF14} OR WHEN {&M_SOF15} THEN DO:
/* we have found the right block, let's extract the values */
ASSIGN
opcType = "image/jpeg"
opiHeight = GET-BYTE(mImage, iPos + 4) * 256 + GET-BYTE(mImage, iPos + 5)
opiWidth = GET-BYTE(mImage, iPos + 6) * 256 + GET-BYTE(mImage, iPos + 7).
LEAVE blkMarkers.
END.
WHEN {&M_SOS} OR WHEN {&M_EOI} THEN
LEAVE blkMarkers.
OTHERWISE /* keep looking */
lSkip = YES.
END CASE.
IF lSkip THEN DO:
iPos = iPos + 256 * GET-BYTE(mImage, iPos + 1) + GET-BYTE(mImage, iPos + 2).
IF iPos >= GET-SIZE(mImage) - 10 THEN DO:
SET-SIZE(mImage) = 0.
RETURN.
END.
END.
END. /* blkMarkers: DO WHILE TRUE */
END. /* JPG */
ELSE IF GET-BYTES(mImage, 1, 6) MATCHES "GIF..a" /* GIF87a or GIF89a */ THEN DO:
ASSIGN
opcType = "image/gif"
opiWidth = 256 * GET-BYTE(mImage, 8) + GET-BYTE(mImage, 7)
opiHeight = 256 * GET-BYTE(mImage, 10) + GET-BYTE(mImage, 9).
END. /* GIF */
ELSE IF GET-BYTES(mImage, 1, 2) = "BM" THEN DO:
ASSIGN
opcType = "image/bmp"
opiWidth = GET-UNSIGNED-LONG(mImage, 19)
opiHeight = GET-UNSIGNED-LONG(mImage, 23).
END. /* BMP */
SET-SIZE(mImage) = 0.
END METHOD.