Thanks to "fabulouspaul" for "libjpeg-turbo" hint, "wilbert" for "libjpeg-turbo" working sample code and the SDK developers, the problem with 8bit grey(gray)scale jpeg is solved finally.
Code: Select all
;{ PreStart
#lib_static = #False
#lib_ver = "2.0.1";"2.0.0";"1.5.3"
;}
;??? #define TJSCALED(dimension, scalingFactor) \
; ((dimension * scalingFactor.num + scalingFactor.denom - 1) / \
; scalingFactor.denom)
; tjtransform:
;??? Int (*customFilter) (short *coeffs, tjregion arrayRegion,
; tjregion planeRegion, int componentIndex,
; int transformIndex, struct tjtransform *transform);
;{ Const
#TJ_NUMSAMP = 6
Enumeration TJCS
#TJCS_RGB = 0
#TJCS_YCbCr
#TJCS_GRAY
#TJCS_CMYK
#TJCS_YCCK
EndEnumeration
#TJ_NUMERR = 2
Enumeration TJERR
#TJERR_WARNING = 0
#TJERR_FATAL
EndEnumeration
#TJ_NUMXOP = 8
Enumeration TJXOP
#TJXOP_NONE = 0
#TJXOP_HFLIP
#TJXOP_VFLIP
#TJXOP_TRANSPOSE
#TJXOP_TRANSVERSE
#TJXOP_ROT90
#TJXOP_ROT180
#TJXOP_ROT270
EndEnumeration
#TJXOPT_PERFECT = 1
#TJXOPT_TRIM = 2
#TJXOPT_CROP = 4
#TJXOPT_GRAY = 8
#TJXOPT_NOOUTPUT = 16
#TJXOPT_PROGRESSIVE = 32
#TJXOPT_COPYNONE = 64
#TJPF_UNKNOWN = -1
Enumeration
#TJPF_RGB
#TJPF_BGR
#TJPF_RGBX
#TJPF_BGRX
#TJPF_XBGR
#TJPF_XRGB
#TJPF_GRAY
#TJPF_RGBA
#TJPF_BGRA
#TJPF_ABGR
#TJPF_ARGB
#TJPF_CMYK
EndEnumeration
Enumeration
#TJSAMP_444
#TJSAMP_422
#TJSAMP_420
#TJSAMP_GRAY
#TJSAMP_440
#TJSAMP_411
EndEnumeration
Enumeration tjMCUWidth ;[TJ_NUMSAMP]
#tjMCUWidth_1 = 8
#tjMCUWidth_2 = 16
#tjMCUWidth_3 = 16
#tjMCUWidth_4 = 8
#tjMCUWidth_5 = 8
#tjMCUWidth_6 = 32
EndEnumeration
Enumeration tjMCUHeight ;[TJ_NUMSAMP]
#tjMCUHeight_1 = 8
#tjMCUHeight_2 = 8
#tjMCUHeight_3 = 16
#tjMCUHeight_4 = 8
#tjMCUHeight_5 = 16
#tjMCUHeight_6 = 8
EndEnumeration
#TJ_NUMCS = 5
#TJ_NUMPF = 12
Enumeration tjRedOffset;[TJ_NUMPF]
#tjRedOffset_1 = 0
#tjRedOffset_2 = 2
#tjRedOffset_3 = 0
#tjRedOffset_4 = 2
#tjRedOffset_5 = 3
#tjRedOffset_6 = 1
#tjRedOffset_7 = -1
#tjRedOffset_8 = 0
#tjRedOffset_9 = 2
#tjRedOffset_10 = 3
#tjRedOffset_11 = 1
#tjRedOffset_12 = -1
EndEnumeration
Enumeration tjGreenOffset;[TJ_NUMPF]
#tjGreenOffset_1 = 1
#tjGreenOffset_2 = 1
#tjGreenOffset_3 = 1
#tjGreenOffset_4 = 1
#tjGreenOffset_5 = 2
#tjGreenOffset_6 = 2
#tjGreenOffset_7 = -1
#tjGreenOffset_8 = 1
#tjGreenOffset_9 = 1
#tjGreenOffset_10 = 2
#tjGreenOffset_11 = 2
#tjGreenOffset_12 = -1
EndEnumeration
Enumeration tjBlueOffset;[TJ_NUMPF] = {
#tjBlueOffset_1 = 2
#tjBlueOffset_2 = 0
#tjBlueOffset_3 = 2
#tjBlueOffset_4 = 0
#tjBlueOffset_5 = 1
#tjBlueOffset_6 = 3
#tjBlueOffset_7 = -1
#tjBlueOffset_8 = 2
#tjBlueOffset_9 = 0
#tjBlueOffset_10 = 1
#tjBlueOffset_11 = 3
#tjBlueOffset_12 = -1
EndEnumeration
Enumeration tjAlphaOffset;[TJ_NUMPF] = {
#tjAlphaOffset_1 = -1
#tjAlphaOffset_2 = -1
#tjAlphaOffset_3 = -1
#tjAlphaOffset_4 = -1
#tjAlphaOffset_5 = -1
#tjAlphaOffset_6 = -1
#tjAlphaOffset_7 = -1
#tjAlphaOffset_8 = 3
#tjAlphaOffset_9 = 3
#tjAlphaOffset_10 = 0
#tjAlphaOffset_11 = 0
#tjAlphaOffset_12 = -1
EndEnumeration
Enumeration tjPixelSize;[TJ_NUMPF] = {
#tjPixelSize_1 = 3
#tjPixelSize_2 = 3
#tjPixelSize_3 = 4
#tjPixelSize_4 = 4
#tjPixelSize_5 = 4
#tjPixelSize_6 = 4
#tjPixelSize_7 = 1
#tjPixelSize_8 = 4
#tjPixelSize_9 = 4
#tjPixelSize_10 = 4
#tjPixelSize_11 = 4
#tjPixelSize_12 = 4
EndEnumeration
#TJFLAG_BOTTOMUP = 2
#TJFLAG_FASTUPSAMPLE = 256
#TJFLAG_NOREALLOC = 1024
#TJFLAG_FASTDCT = 2048
#TJFLAG_ACCURATEDCT = 4096
#TJFLAG_STOPONWARNING = 8192
#TJFLAG_PROGRESSIVE = 16384
; /* Deprecated functions And macros */
#TJFLAG_FORCEMMX = 8
#TJFLAG_FORCESSE = 16
#TJFLAG_FORCESSE2 = 32
#TJFLAG_FORCESSE3 = 128
; /* Backward compatibility functions And macros (nothing To see here) */
#NUMSUBOPT = #TJ_NUMSAMP
#TJ_444 = #TJSAMP_444
#TJ_422 = #TJSAMP_422
#TJ_420 = #TJSAMP_420
#TJ_411 = #TJSAMP_420
#TJ_GRAYSCALE = #TJSAMP_GRAY
#TJ_BGR = 1
#TJ_BOTTOMUP = #TJFLAG_BOTTOMUP
#TJ_FORCEMMX = #TJFLAG_FORCEMMX
#TJ_FORCESSE = #TJFLAG_FORCESSE
#TJ_FORCESSE2 = #TJFLAG_FORCESSE2
#TJ_ALPHAFIRST = 64
#TJ_FORCESSE3 = #TJFLAG_FORCESSE3
#TJ_FASTUPSAMPLE = #TJFLAG_FASTUPSAMPLE
#TJ_YUV = 512
;}
;{ Struct
CompilerIf Defined(tjscalingfactor, #PB_Structure) = #False
Structure tjscalingfactor
num.l
denom.l
EndStructure
CompilerEndIf
CompilerIf Defined(tjregion, #PB_Structure) = #False
Structure tjregion
x.l
y.l
w.l
h.l
EndStructure
CompilerEndIf
CompilerIf Defined(tjtransform, #PB_Structure) = #False
Structure tjtransform
r.tjregion
op.l
options.l
*JPData
; /**
; * A callback function that can be used To modify the DCT coefficients
; * after they are losslessly transformed but before they are transcoded To a
; * new JPEG image. This allows For custom filters Or other transformations
; * To be applied in the frequency domain.
; *
; * @param coeffs pointer To an Array of transformed DCT coefficients. (NOTE:
; * this pointer is Not guaranteed To be valid once the callback returns, so
; * applications wishing To hand off the DCT coefficients To another function
; * Or library should make a copy of them within the body of the callback.)
; *
; * @param arrayRegion #tjregion Structure containing the width And height of
; * the Array pointed To by <tt>coeffs</tt> As well As its offset relative To
; * the component plane. TurboJPEG implementations may choose To split each
; * component plane into multiple DCT coefficient arrays And call the callback
; * function once For each Array.
; *
; * @param planeRegion #tjregion Structure containing the width And height of
; * the component plane To which <tt>coeffs</tt> belongs
; *
; * @param componentID ID number of the component plane To which
; * <tt>coeffs</tt> belongs (Y, Cb, And Cr have, respectively, ID's of 0, 1,
; * And 2 in typical JPEG images.)
; *
; * @param transformID ID number of the transformed image To which
; * <tt>coeffs</tt> belongs. This is the same As the index of the transform
; * in the <tt>transforms</tt> Array that was passed To #tjTransform().
; *
; * @param transform a pointer To a #tjtransform Structure that specifies the
; * parameters And/Or cropping region For this transform
; *
; * @return 0 If the callback was successful, Or -1 If an error occurred.
; */
;??? Int (*customFilter) (short *coeffs, tjregion arrayRegion,
; tjregion planeRegion, int componentIndex,
; int transformIndex, struct tjtransform *transform);
EndStructure
CompilerEndIf
;}
Macro TJPAD(width)
(((width) + 3) & (~3))
EndMacro
CompilerIf #lib_static = #True
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
#LIBTURBO = "v"+#lib_ver+"/libjpeg-turbo/lib/turbojpeg-Static.lib"
CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
#LIBTURBO = "v"+#lib_ver+"/libjpeg-turbo64/lib/turbojpeg-static.lib"
CompilerEndIf
Macro JPTpreInit()
ImportC #LIBTURBO
tjAlloc(bytes)
tjCompress2.l(handle, *srcBuf, width, pitch, height, pixelFormat, *p_jpegBuf, *jpegSize, jpegSubsamp, jpegQual, flags)
tjDecompress2.l(handle, *jpegBuf, jpegSize, *dstBuf, width, pitch, height, pixelFormat, flags)
tjDecompressHeader3.l(handle, *jpegBuf, jpegSize, *width, *height, *jpegSubsamp, *jpegColorspace)
tjFree(*buffer)
tjGetErrorStr()
tjInitCompress()
tjInitDecompress()
; tjInitCompress();DLLEXPORT tjhandle
; tjCompress2.l(handle, *srcBuf, width, pitch, height, pixelFormat, *p_jpegBuf, *jpegSize, jpegSubsamp, jpegQual, flags);DLLEXPORT int
tjCompressFromYUV.l(handle, *srcBuf, width, pad, height, subsamp, *p_jpegBuf, *jpegSize, jpegQual, flags);DLLEXPORT int
tjCompressFromYUVPlanes.l(handle, *p_srcPlanes, width, *strides, height, subsamp, *p_jpegBuf, *jpegSize, jpegQual, flags);DLLEXPORT int
tjBufSize.l(width, height, jpegSubsamp);DLLEXPORT unsigned long
tjBufSizeYUV2.l(width, pad, height, subsamp);DLLEXPORT unsigned long
tjPlaneSizeYUV.l(componentID, width, stride, height, subsamp);DLLEXPORT unsigned long
tjPlaneWidth.l(componentID, width, subsamp);DLLEXPORT int
tjPlaneHeight.l(componentID, height, subsamp);DLLEXPORT int
tjEncodeYUV3.l(handle, *srcBuf, width, pitch, height, pixelFormat, *dstBuf, pad, subsamp, flags);DLLEXPORT int
tjEncodeYUVPlanes.l(handle, *srcBuf, width, pitch, height, pixelFormat, *p_dstPlanes, *strides, subsamp, flags);DLLEXPORT int
; tjInitDecompress.l();DLLEXPORT tjhandle
; tjDecompressHeader3.l(handle, *jpegBuf, jpegSize, *width, *height, *jpegSubsamp, *jpegColorspace);DLLEXPORT int
tjGetScalingFactors.l(*numscalingfactors);DLLEXPORT tjscalingfactor *
; tjDecompress2.l(handle, *jpegBuf, jpegSize, *dstBuf, width, pitch, height, pixelFormat, flags);DLLEXPORT int
tjDecompressToYUV2.l(handle, *jpegBuf, jpegSize, *dstBuf, width, pad, height, flags);DLLEXPORT int
tjDecompressToYUVPlanes.l(handle, *jpegBuf, jpegSize, *p_dstPlanes, width, *strides, height, flags);DLLEXPORT int
tjDecodeYUV.l(handle, *srcBuf, pad, subsamp, *dstBuf, width, pitch, height, pixelFormat, flags);DLLEXPORT int
tjDecodeYUVPlanes.l(handle, *p_srcPlanes, *strides, subsamp, *dstBuf, width, pitch, height, pixelFormat, flags);DLLEXPORT int
tjInitTransform.l();DLLEXPORT tjhandle
tjTransform.l(handle, *jpegBuf, jpegSize, n, *p_dstBufs, *dstSizes, *transforms.tjtransform, flags);DLLEXPORT int
tjDestroy.l(handle);DLLEXPORT int
; tjAlloc.l(bytes);DLLEXPORT unsigned char *
tjLoadImage.l(*filename, *width, align, *height, *pixelFormat, flags);DLLEXPORT unsigned char *
tjSaveImage.l(*filename, *buffer, width, pitch, height, pixelFormat, flags);DLLEXPORT int
; tjFree(*buffer);DLLEXPORT void
tjGetErrorStr2.l(handle);DLLEXPORT char *
tjGetErrorCode.l(handle);DLLEXPORT int
; TJBUFSIZE.l(width, height);DLLEXPORT unsigned long
; TJBUFSIZEYUV.l(width, height, jpegSubsamp);DLLEXPORT unsigned long
tjBufSizeYUV.l(width, height, subsamp);DLLEXPORT unsigned long
tjCompress.l(handle, *srcBuf, width, pitch, height, pixelSize, *dstBuf, *compressedSize, jpegSubsamp, jpegQual, flags);DLLEXPORT int
tjEncodeYUV.l(handle, *srcBuf, width, pitch, height, pixelSize, *dstBuf, subsamp, flags);DLLEXPORT int
tjEncodeYUV2.l(handle, *srcBuf, width, pitch, height, pixelFormat, *dstBuf, subsamp, flags);DLLEXPORT int
tjDecompressHeader.l(handle, *jpegBuf, jpegSize, *width, *height);DLLEXPORT int
tjDecompressHeader2.l(handle, *jpegBuf, jpegSize, *width, *height, *jpegSubsamp);DLLEXPORT int
tjDecompress.l(handle, *jpegBuf, jpegSize, *dstBuf, width, pitch, height, pixelSize, flags);DLLEXPORT int
tjDecompressToYUV.l(handle, *jpegBuf, jpegSize, *dstBuf, flags);DLLEXPORT int
; tjGetErrorStr.l();DLLEXPORT char *
EndImport
EndMacro
CompilerElse
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
#LIBTURBO = "v"+#lib_ver+"/libjpeg-turbo/bin/turbojpeg.dll"
CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
#LIBTURBO = "v"+#lib_ver+"/libjpeg-turbo64/bin/turbojpeg.dll"
CompilerEndIf
Procedure InitLibJPTurbo()
Protected trjpLib = OpenLibrary(#PB_Any, #LIBTURBO)
If trjpLib And IsLibrary(trjpLib)
ProcedureReturn trjpLib
EndIf
ProcedureReturn #False
EndProcedure
Macro JPTpreInit()
trjpLib = InitLibJPTurbo()
PrototypeC.l proto_tjAlloc(bytes) : Global tjAlloc.proto_tjAlloc = GetFunction(trjpLib,"tjAlloc")
PrototypeC.l proto_tjCompress2(handle, *srcBuf, width, pitch, height, pixelFormat, *p_jpegBuf, *jpegSize, jpegSubsamp, jpegQual, flags) : Global tjCompress2.proto_tjCompress2 = GetFunction(trjpLib,"tjCompress2")
PrototypeC.l proto_tjDecompress2(handle, *jpegBuf, jpegSize, *dstBuf, width, pitch, height, pixelFormat, flags) : Global tjDecompress2.proto_tjDecompress2 = GetFunction(trjpLib,"tjDecompress2")
PrototypeC.l proto_tjDecompressHeader3(handle, *jpegBuf, jpegSize, *width, *height, *jpegSubsamp, *jpegColorspace) : Global tjDecompressHeader3.proto_tjDecompressHeader3 = GetFunction(trjpLib,"tjDecompressHeader3")
PrototypeC.l proto_tjFree(*buffer) : Global tjFree.proto_tjFree = GetFunction(trjpLib,"tjFree")
PrototypeC.l proto_tjGetErrorStr() : Global tjGetErrorStr.proto_tjGetErrorStr = GetFunction(trjpLib,"tjGetErrorStr")
PrototypeC.l proto_tjInitCompress() : Global tjInitCompress.proto_tjInitCompress = GetFunction(trjpLib,"tjInitCompress")
PrototypeC.l proto_tjInitDecompress() : Global tjInitDecompress.proto_tjInitDecompress = GetFunction(trjpLib,"tjInitDecompress")
; tjInitCompress();DLLEXPORT tjhandle
; tjCompress2.l(handle, *srcBuf, width, pitch, height, pixelFormat, *p_jpegBuf, *jpegSize, jpegSubsamp, jpegQual, flags);DLLEXPORT int
PrototypeC.l proto_tjCompressFromYUV(handle, *srcBuf, width, pad, height, subsamp, *p_jpegBuf, *jpegSize, jpegQual, flags) : Global tjCompressFromYUV.proto_tjCompressFromYUV = GetFunction(trjpLib,"tjCompressFromYUV")
PrototypeC.l proto_tjCompressFromYUVPlanes(handle, *p_srcPlanes, width, *strides, height, subsamp, *p_jpegBuf, *jpegSize, jpegQual, flags) : Global tjCompressFromYUVPlanes.proto_tjCompressFromYUVPlanes = GetFunction(trjpLib,"tjCompressFromYUVPlanes")
PrototypeC.l proto_tjBufSize(width, height, jpegSubsamp) : Global tjBufSize.proto_tjBufSize = GetFunction(trjpLib,"tjBufSize")
PrototypeC.l proto_tjBufSizeYUV2(width, pad, height, subsamp) : Global tjBufSizeYUV2.proto_tjBufSizeYUV2 = GetFunction(trjpLib,"tjBufSizeYUV2")
PrototypeC.l proto_tjPlaneSizeYUV(componentID, width, stride, height, subsamp) : Global tjPlaneSizeYUV.proto_tjPlaneSizeYUV = GetFunction(trjpLib,"tjPlaneSizeYUV")
PrototypeC.l proto_tjPlaneWidth(componentID, width, subsamp) : Global tjPlaneWidth.proto_tjPlaneWidth = GetFunction(trjpLib,"tjPlaneWidth")
PrototypeC.l proto_tjPlaneHeight(componentID, height, subsamp) : Global tjPlaneHeight.proto_tjPlaneHeight = GetFunction(trjpLib,"tjPlaneHeight")
PrototypeC.l proto_tjEncodeYUV3(handle, *srcBuf, width, pitch, height, pixelFormat, *dstBuf, pad, subsamp, flags) : Global tjEncodeYUV3.proto_tjEncodeYUV3 = GetFunction(trjpLib,"tjEncodeYUV3")
PrototypeC.l proto_tjEncodeYUVPlanes(handle, *srcBuf, width, pitch, height, pixelFormat, *p_dstPlanes, *strides, subsamp, flags) : Global tjEncodeYUVPlanes.proto_tjEncodeYUVPlanes = GetFunction(trjpLib,"tjEncodeYUVPlanes")
; tjInitDecompress.l();DLLEXPORT tjhandle
; tjDecompressHeader3.l(handle, *jpegBuf, jpegSize, *width, *height, *jpegSubsamp, *jpegColorspace);DLLEXPORT int
PrototypeC.l proto_tjGetScalingFactors(*numscalingfactors) : Global tjGetScalingFactors.proto_tjGetScalingFactors = GetFunction(trjpLib,"tjGetScalingFactors")
; tjDecompress2.l(handle, *jpegBuf, jpegSize, *dstBuf, width, pitch, height, pixelFormat, flags);DLLEXPORT int
PrototypeC.l proto_tjDecompressToYUV2(handle, *jpegBuf, jpegSize, *dstBuf, width, pad, height, flags) : Global tjDecompressToYUV2.proto_tjDecompressToYUV2 = GetFunction(trjpLib,"tjDecompressToYUV2")
PrototypeC.l proto_tjDecompressToYUVPlanes(handle, *jpegBuf, jpegSize, *p_dstPlanes, width, *strides, height, flags) : Global tjDecompressToYUVPlanes.proto_tjDecompressToYUVPlanes = GetFunction(trjpLib,"tjDecompressToYUVPlanes")
PrototypeC.l proto_tjDecodeYUV(handle, *srcBuf, pad, subsamp, *dstBuf, width, pitch, height, pixelFormat, flags) : Global tjDecodeYUV.proto_tjDecodeYUV = GetFunction(trjpLib,"tjDecodeYUV")
PrototypeC.l proto_tjDecodeYUVPlanes(handle, *p_srcPlanes, *strides, subsamp, *dstBuf, width, pitch, height, pixelFormat, flags) : Global tjDecodeYUVPlanes.proto_tjDecodeYUVPlanes = GetFunction(trjpLib,"tjDecodeYUVPlanes")
PrototypeC.l proto_tjInitTransform() : Global tjInitTransform.proto_tjInitTransform = GetFunction(trjpLib,"tjInitTransform")
PrototypeC.l proto_tjTransform(handle, *jpegBuf, jpegSize, n, *p_dstBufs, *dstSizes, *transforms.tjtransform, flags) : Global tjTransform.proto_tjTransform = GetFunction(trjpLib,"tjTransform")
PrototypeC.l proto_tjDestroy(handle) : Global tjDestroy.proto_tjDestroy = GetFunction(trjpLib,"tjDestroy")
; tjAlloc.l(bytes);DLLEXPORT unsigned char *
PrototypeC.l proto_tjLoadImage(*filename, *width, align, *height, *pixelFormat, flags) : Global tjLoadImage.proto_tjLoadImage = GetFunction(trjpLib,"tjLoadImage")
PrototypeC.l proto_tjSaveImage(*filename, *buffer, width, pitch, height, pixelFormat, flags) : Global tjSaveImage.proto_tjSaveImage = GetFunction(trjpLib,"tjSaveImage")
; tjFree(*buffer);DLLEXPORT void
PrototypeC.l proto_tjGetErrorStr2(handle) : Global tjGetErrorStr2.proto_tjGetErrorStr2 = GetFunction(trjpLib,"tjGetErrorStr2")
PrototypeC.l proto_tjGetErrorCode(handle) : Global tjGetErrorCode.proto_tjGetErrorCode = GetFunction(trjpLib,"tjGetErrorCode")
; TJBUFSIZE.l(width, height);DLLEXPORT unsigned long
; TJBUFSIZEYUV.l(width, height, jpegSubsamp);DLLEXPORT unsigned long
PrototypeC.l proto_tjBufSizeYUV(width, height, subsamp) : Global tjBufSizeYUV.proto_tjBufSizeYUV = GetFunction(trjpLib,"tjBufSizeYUV")
PrototypeC.l proto_tjCompress(handle, *srcBuf, width, pitch, height, pixelSize, *dstBuf, *compressedSize, jpegSubsamp, jpegQual, flags) : Global tjCompress.proto_tjCompress = GetFunction(trjpLib,"tjCompress")
PrototypeC.l proto_tjEncodeYUV(handle, *srcBuf, width, pitch, height, pixelSize, *dstBuf, subsamp, flags) : Global tjEncodeYUV.proto_tjEncodeYUV = GetFunction(trjpLib,"tjEncodeYUV")
PrototypeC.l proto_tjEncodeYUV2(hande, *srcBuf, width, pitch, height, pixelFormat, *dstBuf, subsamp, flags) : Global tjEncodeYUV2.proto_tjEncodeYUV2 = GetFunction(trjpLib,"tjEncodeYUV2")
PrototypeC.l proto_tjDecompressHeader(handle, *jpegBuf, jpegSize, *width, *height) : Global tjDecompressHeader.proto_tjDecompressHeader = GetFunction(trjpLib,"tjDecompressHeader")
PrototypeC.l proto_tjDecompressHeader2(handle, *jpegBuf, jpegSize, *width, *height, *jpegSubsamp) : Global tjDecompressHeader2.proto_tjDecompressHeader2 = GetFunction(trjpLib,"tjDecompressHeader2")
PrototypeC.l proto_tjDecompress(handle, *jpegBuf, jpegSize, *dstBuf, width, pitch, height, pixelSize, flags) : Global tjDecompress.proto_tjDecompress = GetFunction(trjpLib,"tjDecompress")
PrototypeC.l proto_tjDecompressToYUV(handle, *jpegBuf, jpegSize, *dstBuf, flags) : Global tjDecompressToYUV.proto_tjDecompressToYUV = GetFunction(trjpLib,"tjDecompressToYUV")
; tjGetErrorStr.l();DLLEXPORT char *
EndMacro
CompilerEndIf
Macro JPTinit()
JPTpreInit()
; TJPF from PB PixelFormat
Procedure TJPF_(Format)
If Format & #PB_PixelFormat_32Bits_RGB
ProcedureReturn #TJPF_RGBA
ElseIf Format & #PB_PixelFormat_24Bits_RGB
ProcedureReturn #TJPF_RGB
ElseIf Format & #PB_PixelFormat_32Bits_BGR
ProcedureReturn #TJPF_BGRA
Else
ProcedureReturn #TJPF_BGR
EndIf
EndProcedure
Procedure.i CatchImage_(Image, *Memory, Size)
Protected.i result, w, h, subs, cs, r, pf, flags
If PeekL(*Memory) & $ffffff <> $ffd8ff
ProcedureReturn CatchImage(Image, *Memory, Size)
ElseIf tjDecompressHeader3(tjD, *Memory, Size, @w, @h, @subs, @cs) = 0 And w And h
result = CreateImage(Image, w, h, 24)
If result
If Image = #PB_Any : Image = result : EndIf
StartDrawing(ImageOutput(Image))
pf = DrawingBufferPixelFormat() : flags = #TJFLAG_ACCURATEDCT
If pf & #PB_PixelFormat_ReversedY : flags | #TJFLAG_BOTTOMUP : EndIf
r = tjDecompress2(tjD, *Memory, Size, DrawingBuffer(), w, DrawingBufferPitch(), h, TJPF_(pf), flags)
StopDrawing()
If r
FreeImage(Image) : result = 0
EndIf
EndIf
EndIf
ProcedureReturn result
EndProcedure
Procedure LoadJPEG(Image, FileName.s)
Protected.i result, fhandle, size, w, h, subs, cs, r, pf, flags, sig.l, *buffer.Long
fhandle = ReadFile(#PB_Any, FileName)
If fhandle
size = Lof(fhandle)
If size > 96
sig = ReadLong(fhandle)
If sig & $ffffff = $ffd8ff; possible jpeg
*buffer = AllocateMemory(size, #PB_Memory_NoClear)
If *buffer
*buffer\l = sig
ReadData(fhandle, *buffer + 4, size - 4)
; jpeg decompression
If tjDecompressHeader3(tjD, *buffer, size, @w, @h, @subs, @cs) = 0 And w And h
; create image
result = CreateImage(Image, w, h, 24)
If result
If Image = #PB_Any : Image = result : EndIf
StartDrawing(ImageOutput(Image))
pf = DrawingBufferPixelFormat() : flags = #TJFLAG_ACCURATEDCT
If pf & #PB_PixelFormat_ReversedY : flags | #TJFLAG_BOTTOMUP : EndIf
r = tjDecompress2(tjD, *buffer, size, DrawingBuffer(), w, DrawingBufferPitch(), h, TJPF_(pf), flags)
StopDrawing()
If r
FreeImage(Image) : result = 0
EndIf
EndIf
EndIf
FreeMemory(*buffer)
EndIf
EndIf
EndIf
CloseFile(fhandle)
EndIf
ProcedureReturn result
EndProcedure
Procedure SaveJPEG(Image, FileName.s, quality = 95)
Protected.i result, pf, flags, r, size, fhandle, *buffer
If IsImage(Image) And StartDrawing(ImageOutput(Image))
pf = DrawingBufferPixelFormat()
If quality < 1 : quality = 1 : ElseIf quality > 100 : quality = 100 : EndIf
If quality > 80 : flags = #TJFLAG_ACCURATEDCT : Else : flags = #TJFLAG_FASTDCT : EndIf
If pf & #PB_PixelFormat_ReversedY : flags | #TJFLAG_BOTTOMUP : EndIf
r = tjCompress2(tjC, DrawingBuffer(), OutputWidth(), DrawingBufferPitch(), OutputHeight(), TJPF_(pf), @*buffer, @size, #TJSAMP_444, quality, flags)
StopDrawing()
If r = 0
fhandle = CreateFile(#PB_Any, FileName)
If fhandle
If WriteData(fhandle, *buffer, size) = size
result = #True
EndIf
CloseFile(fhandle)
EndIf
EndIf
tjFree(*buffer)
EndIf
ProcedureReturn result
EndProcedure
EndMacro
CompilerIf #PB_Compiler_IsMainFile
; generate image data
JPTinit()
Dim ImageData.l(255, 255)
For y = 0 To 255
For x = 0 To 255
ImageData(y, x) = x << 16 | y << 8 | (x ! y)
Next
Next
; write jpeg file
Define tjC = tjInitCompress()
*buffer = 0
; tjDecompressHeader3(handle, ?jpeg_start, ?jpeg_end - ?jpeg_start, @width, @height, @subsamp, @cs)
; *m = AllocateMemory(width * height * 4, #PB_Memory_NoClear)
; tjDecompress2(handle, ?jpeg_start, ?jpeg_end - ?jpeg_start, *m, width, 0, height, #TJPF_BGRX, 0)
; DataSection
; jpeg_start:
; IncludeBinary "test.jpg"
; jpeg_end:
; EndDataSection
If tjCompress2(tjC, @ImageData(), 256, 1024, 256, #TJPF_GRAY, @*buffer, @size, #TJSAMP_GRAY, 95, #TJFLAG_ACCURATEDCT) = 0
If CreateFile(0, "libturbojpeg_test.jpg")
WriteData(0, *buffer, size)
CloseFile(0)
EndIf
tjFree(*buffer)
EndIf
CompilerEndIf