zxing_cpp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.gitmodules +3 -0
- data/CHANGELOG.rdoc +6 -0
- data/Gemfile +3 -0
- data/Manifest.txt +331 -0
- data/README.rdoc +138 -0
- data/Rakefile +28 -0
- data/bin/zxd +87 -0
- data/bin/zxe +53 -0
- data/ext/zxing/extconf.rb +27 -0
- data/ext/zxing/zxing-cpp/.gitignore +4 -0
- data/ext/zxing/zxing-cpp/AUTHORS +115 -0
- data/ext/zxing/zxing-cpp/CMakeLists.txt +84 -0
- data/ext/zxing/zxing-cpp/COPYING +201 -0
- data/ext/zxing/zxing-cpp/NOTICE +65 -0
- data/ext/zxing/zxing-cpp/README.md +50 -0
- data/ext/zxing/zxing-cpp/cli/src/ImageReaderSource.cpp +112 -0
- data/ext/zxing/zxing-cpp/cli/src/ImageReaderSource.h +40 -0
- data/ext/zxing/zxing-cpp/cli/src/jpgd.cpp +3174 -0
- data/ext/zxing/zxing-cpp/cli/src/jpgd.h +319 -0
- data/ext/zxing/zxing-cpp/cli/src/lodepng.cpp +6261 -0
- data/ext/zxing/zxing-cpp/cli/src/lodepng.h +1695 -0
- data/ext/zxing/zxing-cpp/cli/src/main.cpp +297 -0
- data/ext/zxing/zxing-cpp/cmake/FindCPPUNIT.cmake +54 -0
- data/ext/zxing/zxing-cpp/cmake/FindIconv.cmake +57 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/.gitignore +6 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigInteger.cc +405 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigInteger.hh +215 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerAlgorithms.cc +70 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerAlgorithms.hh +25 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerLibrary.hh +8 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerUtils.cc +50 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerUtils.hh +72 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsigned.cc +697 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsigned.hh +418 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsignedInABase.cc +125 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsignedInABase.hh +122 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/ChangeLog +146 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/Makefile +73 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/NumberlikeArray.hh +177 -0
- data/ext/zxing/zxing-cpp/core/src/bigint/README +71 -0
- data/ext/zxing/zxing-cpp/core/src/win32/zxing/iconv.h +14 -0
- data/ext/zxing/zxing-cpp/core/src/win32/zxing/stdint.h +247 -0
- data/ext/zxing/zxing-cpp/core/src/win32/zxing/win_iconv.c +2035 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/BarcodeFormat.cpp +40 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/BarcodeFormat.h +60 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Binarizer.cpp +45 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Binarizer.h +50 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/BinaryBitmap.cpp +70 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/BinaryBitmap.h +56 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ChecksumException.cpp +28 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ChecksumException.h +34 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/DecodeHints.cpp +142 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/DecodeHints.h +85 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Exception.cpp +43 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Exception.h +51 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/FormatException.cpp +41 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/FormatException.h +37 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/IllegalStateException.h +35 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/InvertedLuminanceSource.cpp +68 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/InvertedLuminanceSource.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/LuminanceSource.cpp +86 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/LuminanceSource.h +59 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/MultiFormatReader.cpp +124 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/MultiFormatReader.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/NotFoundException.h +35 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Reader.cpp +31 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Reader.h +40 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ReaderException.h +37 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Result.cpp +61 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/Result.h +55 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ResultIO.cpp +34 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ResultPoint.cpp +108 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ResultPoint.h +55 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ResultPointCallback.cpp +26 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ResultPointCallback.h +39 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/ZXing.h +133 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecDetectorResult.cpp +54 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecDetectorResult.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecReader.cpp +68 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecReader.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/decoder/Decoder.cpp +489 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/decoder/Decoder.h +69 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/detector/Detector.cpp +548 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/aztec/detector/Detector.h +92 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/Array.h +170 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitArray.cpp +155 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitArray.h +81 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitArrayIO.cpp +31 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitMatrix.cpp +143 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitMatrix.h +91 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitSource.cpp +76 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/BitSource.h +74 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/CharacterSetECI.cpp +104 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/CharacterSetECI.h +53 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/Counted.h +140 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/DecoderResult.cpp +46 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/DecoderResult.h +51 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/DetectorResult.cpp +39 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/DetectorResult.h +43 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GlobalHistogramBinarizer.cpp +212 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GlobalHistogramBinarizer.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleLuminanceSource.cpp +80 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleLuminanceSource.h +53 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleRotatedLuminanceSource.cpp +81 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleRotatedLuminanceSource.h +46 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GridSampler.cpp +122 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/GridSampler.h +45 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/HybridBinarizer.cpp +226 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/HybridBinarizer.h +67 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/IllegalArgumentException.cpp +27 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/IllegalArgumentException.h +36 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/PerspectiveTransform.cpp +107 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/PerspectiveTransform.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/Point.h +47 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/Str.cpp +61 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/Str.h +51 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/StringUtils.cpp +198 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/StringUtils.h +52 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/JavaMath.h +43 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/MathUtils.h +57 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/MonochromeRectangleDetector.cpp +174 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/MonochromeRectangleDetector.h +62 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/WhiteRectangleDetector.cpp +330 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/WhiteRectangleDetector.h +59 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGF.cpp +150 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGF.h +73 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGFPoly.cpp +218 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGFPoly.h +56 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonDecoder.cpp +174 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonDecoder.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonException.cpp +30 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonException.h +33 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/DataMatrixReader.cpp +54 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/DataMatrixReader.h +45 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/Version.cpp +199 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/Version.h +87 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/BitMatrixParser.cpp +361 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/BitMatrixParser.h +59 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DataBlock.cpp +113 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DataBlock.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DecodedBitStreamParser.cpp +416 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DecodedBitStreamParser.h +104 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/Decoder.cpp +93 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/Decoder.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/CornerPoint.cpp +46 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/CornerPoint.h +43 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/Detector.cpp +446 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/Detector.h +94 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/DetectorException.cpp +23 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/DetectorException.h +23 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/ByQuadrantReader.cpp +75 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/ByQuadrantReader.h +42 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/GenericMultipleBarcodeReader.cpp +137 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/GenericMultipleBarcodeReader.h +51 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/MultipleBarcodeReader.cpp +29 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/MultipleBarcodeReader.h +41 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/QRCodeMultiReader.cpp +58 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/QRCodeMultiReader.h +36 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiDetector.cpp +47 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiDetector.h +37 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiFinderPatternFinder.cpp +236 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiFinderPatternFinder.h +47 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/CodaBarReader.cpp +340 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/CodaBarReader.h +57 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code128Reader.cpp +496 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code128Reader.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code39Reader.cpp +328 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code39Reader.h +63 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code93Reader.cpp +293 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code93Reader.h +58 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN13Reader.cpp +85 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN13Reader.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN8Reader.cpp +65 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN8Reader.h +47 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/ITFReader.cpp +337 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/ITFReader.h +54 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatOneDReader.cpp +96 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatOneDReader.h +38 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatUPCEANReader.cpp +110 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatUPCEANReader.h +41 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDReader.cpp +227 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDReader.h +81 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDResultPoint.cpp +28 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDResultPoint.h +35 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCAReader.cpp +71 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCAReader.h +50 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEANReader.cpp +309 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEANReader.h +88 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEReader.cpp +146 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEReader.h +47 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/PDF417Reader.cpp +170 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/PDF417Reader.h +49 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/BitMatrixParser.cpp +997 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/BitMatrixParser.h +84 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/DecodedBitStreamParser.cpp +563 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/DecodedBitStreamParser.h +84 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/Decoder.cpp +118 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/Decoder.h +62 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ErrorCorrection.cpp +214 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ErrorCorrection.h +71 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusGF.cpp +120 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusGF.h +72 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusPoly.cpp +284 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusPoly.h +68 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/Detector.cpp +664 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/Detector.h +106 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/LinesSampler.cpp +714 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/LinesSampler.h +122 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/ErrorCorrectionLevel.cpp +65 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/ErrorCorrectionLevel.h +52 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/FormatInformation.cpp +117 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/FormatInformation.h +54 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/QRCodeReader.cpp +52 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/QRCodeReader.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/Version.cpp +560 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/Version.h +85 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/BitMatrixParser.cpp +183 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/BitMatrixParser.h +56 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataBlock.cpp +118 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataBlock.h +50 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataMask.cpp +159 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataMask.h +50 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DecodedBitStreamParser.cpp +425 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DecodedBitStreamParser.h +72 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Decoder.cpp +107 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Decoder.h +46 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Mode.cpp +90 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Mode.h +57 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPattern.cpp +47 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPattern.h +45 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPatternFinder.cpp +208 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPatternFinder.h +68 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/Detector.cpp +314 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/Detector.h +69 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPattern.cpp +69 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPattern.h +48 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternFinder.cpp +559 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternFinder.h +76 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternInfo.cpp +41 -0
- data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternInfo.h +47 -0
- data/ext/zxing/zxing-cpp/core/tests/src/TestRunner.cpp +30 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/BitArrayTest.cpp +216 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/BitArrayTest.h +61 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/BitMatrixTest.cpp +106 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/BitMatrixTest.h +55 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/BitSourceTest.cpp +49 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/BitSourceTest.h +42 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/CountedTest.cpp +58 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/CountedTest.h +46 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/PerspectiveTransformTest.cpp +69 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/PerspectiveTransformTest.h +47 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/reedsolomon/ReedSolomonTest.cpp +129 -0
- data/ext/zxing/zxing-cpp/core/tests/src/common/reedsolomon/ReedSolomonTest.h +62 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/ErrorCorrectionLevelTest.cpp +47 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/ErrorCorrectionLevelTest.h +45 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/FormatInformationTest.cpp +88 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/FormatInformationTest.h +47 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/VersionTest.cpp +88 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/VersionTest.h +49 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/DataMaskTest.cpp +132 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/DataMaskTest.h +91 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/ModeTest.cpp +52 -0
- data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/ModeTest.h +47 -0
- data/ext/zxing/zxing.cc +224 -0
- data/lib/zxing.rb +50 -0
- data/lib/zxing/.gitignore +2 -0
- data/lib/zxing/aztec.rb +5 -0
- data/lib/zxing/aztec/aztec_reader.rb +14 -0
- data/lib/zxing/bad_image_exception.rb +4 -0
- data/lib/zxing/binarizer.rb +8 -0
- data/lib/zxing/binary_bitmap.rb +15 -0
- data/lib/zxing/checksum_exception.rb +4 -0
- data/lib/zxing/common.rb +7 -0
- data/lib/zxing/common/bit_matrix.rb +9 -0
- data/lib/zxing/common/hybrid_binarizer.rb +17 -0
- data/lib/zxing/common/illegal_argument_exception.rb +4 -0
- data/lib/zxing/datamatrix.rb +5 -0
- data/lib/zxing/datamatrix/data_matrix_reader.rb +14 -0
- data/lib/zxing/decodable.rb +11 -0
- data/lib/zxing/exception.rb +4 -0
- data/lib/zxing/ffi.rb +20 -0
- data/lib/zxing/ffi/aztec.rb +6 -0
- data/lib/zxing/ffi/aztec/aztec_reader.rb +9 -0
- data/lib/zxing/ffi/binarizer.rb +25 -0
- data/lib/zxing/ffi/binary_bitmap.rb +15 -0
- data/lib/zxing/ffi/common.rb +8 -0
- data/lib/zxing/ffi/common/bit_matrix.rb +12 -0
- data/lib/zxing/ffi/common/greyscale_luminance_source.rb +30 -0
- data/lib/zxing/ffi/common/hybrid_binarizer.rb +10 -0
- data/lib/zxing/ffi/datamatrix.rb +6 -0
- data/lib/zxing/ffi/datamatrix/data_matrix_reader.rb +9 -0
- data/lib/zxing/ffi/library.rb +102 -0
- data/lib/zxing/ffi/luminance_source.rb +18 -0
- data/lib/zxing/ffi/multi_format_reader.rb +9 -0
- data/lib/zxing/ffi/oned.rb +6 -0
- data/lib/zxing/ffi/oned/code_39_reader.rb +10 -0
- data/lib/zxing/ffi/qrcode.rb +8 -0
- data/lib/zxing/ffi/qrcode/decoder.rb +10 -0
- data/lib/zxing/ffi/qrcode/detector.rb +10 -0
- data/lib/zxing/ffi/reader.rb +58 -0
- data/lib/zxing/ffi/result.rb +23 -0
- data/lib/zxing/format_exception.rb +4 -0
- data/lib/zxing/illegal_argument_exception.rb +4 -0
- data/lib/zxing/image.rb +15 -0
- data/lib/zxing/luminance_source.rb +18 -0
- data/lib/zxing/multi_format_reader.rb +11 -0
- data/lib/zxing/not_found_exception.rb +4 -0
- data/lib/zxing/oned.rb +5 -0
- data/lib/zxing/oned/code_39_reader.rb +15 -0
- data/lib/zxing/qrcode.rb +8 -0
- data/lib/zxing/qrcode/decoder.rb +14 -0
- data/lib/zxing/qrcode/detector.rb +14 -0
- data/lib/zxing/qrcode/encoder.rb +8 -0
- data/lib/zxing/qrcode/encoder/byte_matrix.rb +18 -0
- data/lib/zxing/qrcode/encoder/encoder.rb +9 -0
- data/lib/zxing/qrcode/encoder/qrcode.rb +18 -0
- data/lib/zxing/reader.rb +8 -0
- data/lib/zxing/reader_exception.rb +4 -0
- data/lib/zxing/reed_solomon_exception.rb +2 -0
- data/lib/zxing/result.rb +18 -0
- data/lib/zxing/rmagick.rb +5 -0
- data/lib/zxing/rmagick/image.rb +104 -0
- data/lib/zxing/version.rb +33 -0
- data/test/qrcode.png +0 -0
- data/test/test_helper.rb +5 -0
- data/test/test_zxing.rb +58 -0
- data/test/vendor.rb +360 -0
- data/test/zxing/test_decodable.rb +38 -0
- data/zxing_cpp.gemspec +48 -0
- metadata +473 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--------------------------------------------------------------------------------
|
|
2
|
+
NOTICES FOR ISO C9x compliant stdint.h for Microsoft Visual Studio
|
|
3
|
+
--------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2006-2008 Alexander Chemeris
|
|
8
|
+
|
|
9
|
+
Redistribution and use in source and binary forms, with or without
|
|
10
|
+
modification, are permitted provided that the following conditions are met:
|
|
11
|
+
|
|
12
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer.
|
|
14
|
+
|
|
15
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
16
|
+
notice, this list of conditions and the following disclaimer in the
|
|
17
|
+
documentation and/or other materials provided with the distribution.
|
|
18
|
+
|
|
19
|
+
3. The name of the author may be used to endorse or promote products
|
|
20
|
+
derived from this software without specific prior written permission.
|
|
21
|
+
|
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
23
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
24
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
25
|
+
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
26
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
27
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
28
|
+
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
29
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
30
|
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
31
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
32
|
+
|
|
33
|
+
--------------------------------------------------------------------------------
|
|
34
|
+
NOTICES FOR LodePNG
|
|
35
|
+
--------------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
Copyright (c) 2005-2013 Lode Vandevenne
|
|
38
|
+
|
|
39
|
+
This software is provided 'as-is', without any express or implied
|
|
40
|
+
warranty. In no event will the authors be held liable for any damages
|
|
41
|
+
arising from the use of this software.
|
|
42
|
+
|
|
43
|
+
Permission is granted to anyone to use this software for any purpose,
|
|
44
|
+
including commercial applications, and to alter it and redistribute it
|
|
45
|
+
freely, subject to the following restrictions:
|
|
46
|
+
|
|
47
|
+
1. The origin of this software must not be misrepresented; you must not
|
|
48
|
+
claim that you wrote the original software. If you use this software
|
|
49
|
+
in a product, an acknowledgment in the product documentation would be
|
|
50
|
+
appreciated but is not required.
|
|
51
|
+
|
|
52
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
|
53
|
+
misrepresented as being the original software.
|
|
54
|
+
|
|
55
|
+
3. This notice may not be removed or altered from any source
|
|
56
|
+
distribution.
|
|
57
|
+
|
|
58
|
+
--------------------------------------------------------------------------------
|
|
59
|
+
NOTICES FOR C++ Big Integer Library
|
|
60
|
+
--------------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
I, Matt McCutchen, the sole author of the original Big Integer
|
|
63
|
+
Library, waive my copyright to it, placing it in the public domain.
|
|
64
|
+
The library comes with absolutely no warranty.
|
|
65
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# ZXing C++ Port
|
|
2
|
+
|
|
3
|
+
[ZXing](https://github.com/zxing/zxing) is/was a Java library.
|
|
4
|
+
|
|
5
|
+
At some point a complete C++ port/rewrite was created and maintained in the official [ZXing](https://github.com/zxing/zxing) repo. However, at the time of writing the C++ port is no longer maintained and has been removed from the official ZXing repo.
|
|
6
|
+
|
|
7
|
+
This project was forked from the [last ZXing commit](https://github.com/zxing/zxing/commit/00f6340) to contain the C++ project, with the following exceptions
|
|
8
|
+
|
|
9
|
+
* scons (Python) build system has been deleted.
|
|
10
|
+
* Deleted black box tests, because they refer to a large test data in ZXing repo.
|
|
11
|
+
* Added appropriate copyright/licensing details (based on those in the ZXing repo).
|
|
12
|
+
* Updated README.md
|
|
13
|
+
|
|
14
|
+
Removal of build systems was done to minimise maintenance burden.
|
|
15
|
+
|
|
16
|
+
If tests and XCode projects (other than those produced automatically be CMake) are desired, then another repo should be created and this repo referenced as a submodule.
|
|
17
|
+
|
|
18
|
+
# Building using CMake
|
|
19
|
+
|
|
20
|
+
CMake is a tool, that generates native makefiles and workspaces. It integrates well with a number of IDEs including Qt Creator and Visual Studio.
|
|
21
|
+
|
|
22
|
+
Usage with CLion or Qt Creator:
|
|
23
|
+
|
|
24
|
+
1. Simply open `CMakeLists.txt` as a new project
|
|
25
|
+
2. Additional command line arguments can be specified (see below)
|
|
26
|
+
|
|
27
|
+
Usage with Makefiles, Visual Studio, etc. (see `cmake --help` for a complete list of generators):
|
|
28
|
+
|
|
29
|
+
1. `cd` to `cpp/build`
|
|
30
|
+
3. Unix: run `cmake -G "Unix Makefiles" ..`
|
|
31
|
+
3. Windows: run `cmake -G "Visual Studio 10" ..`
|
|
32
|
+
|
|
33
|
+
You can switch between build modes by specifying:
|
|
34
|
+
|
|
35
|
+
- `-DCMAKE_BUILD_TYPE=Debug` or
|
|
36
|
+
- `-DCMAKE_BUILD_TYPE=Release`
|
|
37
|
+
|
|
38
|
+
# Development tips
|
|
39
|
+
|
|
40
|
+
To profile the code (very useful to optimize the code):
|
|
41
|
+
|
|
42
|
+
1. Install Valgrind
|
|
43
|
+
2. Run `valgrind --tool=callgrind build/zxing - path/to/test/data/*.jpg > report.html`
|
|
44
|
+
3. Analyze output using KCachegrind
|
|
45
|
+
|
|
46
|
+
To run the black box tests and check for changes:
|
|
47
|
+
|
|
48
|
+
1. Build `zxing-img`, e.g., scons zxing
|
|
49
|
+
2. Run the tests: `bash blackboxtest.sh 2>&1 | tee bb.results`
|
|
50
|
+
3. Diff them with the known results: `diff bb.results blackboxtest.results`
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2010-2011 ZXing authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#include "ImageReaderSource.h"
|
|
18
|
+
#include <zxing/common/IllegalArgumentException.h>
|
|
19
|
+
#include <iostream>
|
|
20
|
+
#include <sstream>
|
|
21
|
+
#include <cstdlib>
|
|
22
|
+
#include <algorithm>
|
|
23
|
+
#include "lodepng.h"
|
|
24
|
+
#include "jpgd.h"
|
|
25
|
+
|
|
26
|
+
using std::string;
|
|
27
|
+
using std::ostringstream;
|
|
28
|
+
using zxing::Ref;
|
|
29
|
+
using zxing::ArrayRef;
|
|
30
|
+
using zxing::LuminanceSource;
|
|
31
|
+
|
|
32
|
+
inline char ImageReaderSource::convertPixel(char const* pixel_) const {
|
|
33
|
+
unsigned char const* pixel = (unsigned char const*)pixel_;
|
|
34
|
+
if (comps == 1 || comps == 2) {
|
|
35
|
+
// Gray or gray+alpha
|
|
36
|
+
return pixel[0];
|
|
37
|
+
} if (comps == 3 || comps == 4) {
|
|
38
|
+
// Red, Green, Blue, (Alpha)
|
|
39
|
+
// We assume 16 bit values here
|
|
40
|
+
// 0x200 = 1<<9, half an lsb of the result to force rounding
|
|
41
|
+
return (char)((306 * (int)pixel[0] + 601 * (int)pixel[1] +
|
|
42
|
+
117 * (int)pixel[2] + 0x200) >> 10);
|
|
43
|
+
} else {
|
|
44
|
+
throw zxing::IllegalArgumentException("Unexpected image depth");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
ImageReaderSource::ImageReaderSource(ArrayRef<char> image_, int width, int height, int comps_)
|
|
49
|
+
: Super(width, height), image(image_), comps(comps_) {}
|
|
50
|
+
|
|
51
|
+
Ref<LuminanceSource> ImageReaderSource::create(string const& filename) {
|
|
52
|
+
string extension = filename.substr(filename.find_last_of(".") + 1);
|
|
53
|
+
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
|
54
|
+
int width, height;
|
|
55
|
+
int comps = 0;
|
|
56
|
+
zxing::ArrayRef<char> image;
|
|
57
|
+
if (extension == "png") {
|
|
58
|
+
std::vector<unsigned char> out;
|
|
59
|
+
|
|
60
|
+
{ unsigned w, h;
|
|
61
|
+
unsigned error = lodepng::decode(out, w, h, filename);
|
|
62
|
+
if (error) {
|
|
63
|
+
ostringstream msg;
|
|
64
|
+
msg << "Error while loading '" << lodepng_error_text(error) << "'";
|
|
65
|
+
throw zxing::IllegalArgumentException(msg.str().c_str());
|
|
66
|
+
}
|
|
67
|
+
width = w;
|
|
68
|
+
height = h;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
comps = 4;
|
|
72
|
+
image = zxing::ArrayRef<char>(4 * width * height);
|
|
73
|
+
memcpy(&image[0], &out[0], image->size());
|
|
74
|
+
} else if (extension == "jpg" || extension == "jpeg") {
|
|
75
|
+
char *buffer = reinterpret_cast<char*>(jpgd::decompress_jpeg_image_from_file(
|
|
76
|
+
filename.c_str(), &width, &height, &comps, 4));
|
|
77
|
+
image = zxing::ArrayRef<char>(buffer, 4 * width * height);
|
|
78
|
+
}
|
|
79
|
+
if (!image) {
|
|
80
|
+
ostringstream msg;
|
|
81
|
+
msg << "Loading \"" << filename << "\" failed.";
|
|
82
|
+
throw zxing::IllegalArgumentException(msg.str().c_str());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return Ref<LuminanceSource>(new ImageReaderSource(image, width, height, comps));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
zxing::ArrayRef<char> ImageReaderSource::getRow(int y, zxing::ArrayRef<char> row) const {
|
|
89
|
+
const char* pixelRow = &image[0] + y * getWidth() * 4;
|
|
90
|
+
if (!row) {
|
|
91
|
+
row = zxing::ArrayRef<char>(getWidth());
|
|
92
|
+
}
|
|
93
|
+
for (int x = 0; x < getWidth(); x++) {
|
|
94
|
+
row[x] = convertPixel(pixelRow + (x * 4));
|
|
95
|
+
}
|
|
96
|
+
return row;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** This is a more efficient implementation. */
|
|
100
|
+
zxing::ArrayRef<char> ImageReaderSource::getMatrix() const {
|
|
101
|
+
const char* p = &image[0];
|
|
102
|
+
zxing::ArrayRef<char> matrix(getWidth() * getHeight());
|
|
103
|
+
char* m = &matrix[0];
|
|
104
|
+
for (int y = 0; y < getHeight(); y++) {
|
|
105
|
+
for (int x = 0; x < getWidth(); x++) {
|
|
106
|
+
*m = convertPixel(p);
|
|
107
|
+
m++;
|
|
108
|
+
p += 4;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return matrix;
|
|
112
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
|
|
2
|
+
#ifndef __IMAGE_READER_SOURCE_H_
|
|
3
|
+
#define __IMAGE_READER_SOURCE_H_
|
|
4
|
+
/*
|
|
5
|
+
* Copyright 2010-2011 ZXing authors
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#include <zxing/LuminanceSource.h>
|
|
21
|
+
|
|
22
|
+
class ImageReaderSource : public zxing::LuminanceSource {
|
|
23
|
+
private:
|
|
24
|
+
typedef LuminanceSource Super;
|
|
25
|
+
|
|
26
|
+
const zxing::ArrayRef<char> image;
|
|
27
|
+
const int comps;
|
|
28
|
+
|
|
29
|
+
char convertPixel(const char* pixel) const;
|
|
30
|
+
|
|
31
|
+
public:
|
|
32
|
+
static zxing::Ref<LuminanceSource> create(std::string const& filename);
|
|
33
|
+
|
|
34
|
+
ImageReaderSource(zxing::ArrayRef<char> image, int width, int height, int comps);
|
|
35
|
+
|
|
36
|
+
zxing::ArrayRef<char> getRow(int y, zxing::ArrayRef<char> row) const;
|
|
37
|
+
zxing::ArrayRef<char> getMatrix() const;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
#endif /* __IMAGE_READER_SOURCE_H_ */
|
|
@@ -0,0 +1,3174 @@
|
|
|
1
|
+
// jpgd.cpp - C++ class for JPEG decompression.
|
|
2
|
+
// Public domain, Rich Geldreich <richgel99@gmail.com>
|
|
3
|
+
// Alex Evans: Linear memory allocator (taken from jpge.h).
|
|
4
|
+
// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless)
|
|
5
|
+
//
|
|
6
|
+
// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2.
|
|
7
|
+
//
|
|
8
|
+
// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling.
|
|
9
|
+
// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain"
|
|
10
|
+
// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html
|
|
11
|
+
|
|
12
|
+
#include "jpgd.h"
|
|
13
|
+
#include <string.h>
|
|
14
|
+
|
|
15
|
+
#include <assert.h>
|
|
16
|
+
#define JPGD_ASSERT(x) assert(x)
|
|
17
|
+
|
|
18
|
+
#ifdef _MSC_VER
|
|
19
|
+
#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling).
|
|
23
|
+
// This is slower, but results in higher quality on images with highly saturated colors.
|
|
24
|
+
#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1
|
|
25
|
+
|
|
26
|
+
#define JPGD_TRUE (1)
|
|
27
|
+
#define JPGD_FALSE (0)
|
|
28
|
+
|
|
29
|
+
#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))
|
|
30
|
+
#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))
|
|
31
|
+
|
|
32
|
+
namespace jpgd {
|
|
33
|
+
|
|
34
|
+
static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); }
|
|
35
|
+
static inline void jpgd_free(void *p) { free(p); }
|
|
36
|
+
|
|
37
|
+
// DCT coefficients are stored in this sequence.
|
|
38
|
+
static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 };
|
|
39
|
+
|
|
40
|
+
enum JPEG_MARKER
|
|
41
|
+
{
|
|
42
|
+
M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,
|
|
43
|
+
M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,
|
|
44
|
+
M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,
|
|
45
|
+
M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,
|
|
46
|
+
M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };
|
|
50
|
+
|
|
51
|
+
#define CONST_BITS 13
|
|
52
|
+
#define PASS1_BITS 2
|
|
53
|
+
#define SCALEDONE ((int32)1)
|
|
54
|
+
|
|
55
|
+
#define FIX_0_298631336 ((int32)2446) /* FIX(0.298631336) */
|
|
56
|
+
#define FIX_0_390180644 ((int32)3196) /* FIX(0.390180644) */
|
|
57
|
+
#define FIX_0_541196100 ((int32)4433) /* FIX(0.541196100) */
|
|
58
|
+
#define FIX_0_765366865 ((int32)6270) /* FIX(0.765366865) */
|
|
59
|
+
#define FIX_0_899976223 ((int32)7373) /* FIX(0.899976223) */
|
|
60
|
+
#define FIX_1_175875602 ((int32)9633) /* FIX(1.175875602) */
|
|
61
|
+
#define FIX_1_501321110 ((int32)12299) /* FIX(1.501321110) */
|
|
62
|
+
#define FIX_1_847759065 ((int32)15137) /* FIX(1.847759065) */
|
|
63
|
+
#define FIX_1_961570560 ((int32)16069) /* FIX(1.961570560) */
|
|
64
|
+
#define FIX_2_053119869 ((int32)16819) /* FIX(2.053119869) */
|
|
65
|
+
#define FIX_2_562915447 ((int32)20995) /* FIX(2.562915447) */
|
|
66
|
+
#define FIX_3_072711026 ((int32)25172) /* FIX(3.072711026) */
|
|
67
|
+
|
|
68
|
+
#define DESCALE(x,n) (((x) + (SCALEDONE << ((n)-1))) >> (n))
|
|
69
|
+
#define DESCALE_ZEROSHIFT(x,n) (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n))
|
|
70
|
+
|
|
71
|
+
#define MULTIPLY(var, cnst) ((var) * (cnst))
|
|
72
|
+
|
|
73
|
+
#define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i))
|
|
74
|
+
|
|
75
|
+
// Compiler creates a fast path 1D IDCT for X non-zero columns
|
|
76
|
+
template <int NONZERO_COLS>
|
|
77
|
+
struct Row
|
|
78
|
+
{
|
|
79
|
+
static void idct(int* pTemp, const jpgd_block_t* pSrc)
|
|
80
|
+
{
|
|
81
|
+
// ACCESS_COL() will be optimized at compile time to either an array access, or 0.
|
|
82
|
+
#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)
|
|
83
|
+
|
|
84
|
+
const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);
|
|
85
|
+
|
|
86
|
+
const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
|
87
|
+
const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
|
88
|
+
const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
|
89
|
+
|
|
90
|
+
const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS;
|
|
91
|
+
const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS;
|
|
92
|
+
|
|
93
|
+
const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
|
|
94
|
+
|
|
95
|
+
const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);
|
|
96
|
+
|
|
97
|
+
const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
|
|
98
|
+
const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
|
|
99
|
+
|
|
100
|
+
const int az1 = MULTIPLY(bz1, - FIX_0_899976223);
|
|
101
|
+
const int az2 = MULTIPLY(bz2, - FIX_2_562915447);
|
|
102
|
+
const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5;
|
|
103
|
+
const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5;
|
|
104
|
+
|
|
105
|
+
const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
|
|
106
|
+
const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
|
|
107
|
+
const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
|
|
108
|
+
const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
|
|
109
|
+
|
|
110
|
+
pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS);
|
|
111
|
+
pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS);
|
|
112
|
+
pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS);
|
|
113
|
+
pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS);
|
|
114
|
+
pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS);
|
|
115
|
+
pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS);
|
|
116
|
+
pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS);
|
|
117
|
+
pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
template <>
|
|
122
|
+
struct Row<0>
|
|
123
|
+
{
|
|
124
|
+
static void idct(int* pTemp, const jpgd_block_t* pSrc)
|
|
125
|
+
{
|
|
126
|
+
(void)pTemp;
|
|
127
|
+
(void)pSrc;
|
|
128
|
+
#ifdef _MSC_VER
|
|
129
|
+
pTemp; pSrc;
|
|
130
|
+
#endif
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
template <>
|
|
135
|
+
struct Row<1>
|
|
136
|
+
{
|
|
137
|
+
static void idct(int* pTemp, const jpgd_block_t* pSrc)
|
|
138
|
+
{
|
|
139
|
+
const int dcval = (pSrc[0] << PASS1_BITS);
|
|
140
|
+
|
|
141
|
+
pTemp[0] = dcval;
|
|
142
|
+
pTemp[1] = dcval;
|
|
143
|
+
pTemp[2] = dcval;
|
|
144
|
+
pTemp[3] = dcval;
|
|
145
|
+
pTemp[4] = dcval;
|
|
146
|
+
pTemp[5] = dcval;
|
|
147
|
+
pTemp[6] = dcval;
|
|
148
|
+
pTemp[7] = dcval;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Compiler creates a fast path 1D IDCT for X non-zero rows
|
|
153
|
+
template <int NONZERO_ROWS>
|
|
154
|
+
struct Col
|
|
155
|
+
{
|
|
156
|
+
static void idct(uint8* pDst_ptr, const int* pTemp)
|
|
157
|
+
{
|
|
158
|
+
// ACCESS_ROW() will be optimized at compile time to either an array access, or 0.
|
|
159
|
+
#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)
|
|
160
|
+
|
|
161
|
+
const int z2 = ACCESS_ROW(2);
|
|
162
|
+
const int z3 = ACCESS_ROW(6);
|
|
163
|
+
|
|
164
|
+
const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
|
165
|
+
const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
|
166
|
+
const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
|
167
|
+
|
|
168
|
+
const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS;
|
|
169
|
+
const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS;
|
|
170
|
+
|
|
171
|
+
const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
|
|
172
|
+
|
|
173
|
+
const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);
|
|
174
|
+
|
|
175
|
+
const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
|
|
176
|
+
const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
|
|
177
|
+
|
|
178
|
+
const int az1 = MULTIPLY(bz1, - FIX_0_899976223);
|
|
179
|
+
const int az2 = MULTIPLY(bz2, - FIX_2_562915447);
|
|
180
|
+
const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5;
|
|
181
|
+
const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5;
|
|
182
|
+
|
|
183
|
+
const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
|
|
184
|
+
const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
|
|
185
|
+
const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
|
|
186
|
+
const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
|
|
187
|
+
|
|
188
|
+
int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3);
|
|
189
|
+
pDst_ptr[8*0] = (uint8)CLAMP(i);
|
|
190
|
+
|
|
191
|
+
i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3);
|
|
192
|
+
pDst_ptr[8*7] = (uint8)CLAMP(i);
|
|
193
|
+
|
|
194
|
+
i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3);
|
|
195
|
+
pDst_ptr[8*1] = (uint8)CLAMP(i);
|
|
196
|
+
|
|
197
|
+
i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3);
|
|
198
|
+
pDst_ptr[8*6] = (uint8)CLAMP(i);
|
|
199
|
+
|
|
200
|
+
i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3);
|
|
201
|
+
pDst_ptr[8*2] = (uint8)CLAMP(i);
|
|
202
|
+
|
|
203
|
+
i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3);
|
|
204
|
+
pDst_ptr[8*5] = (uint8)CLAMP(i);
|
|
205
|
+
|
|
206
|
+
i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3);
|
|
207
|
+
pDst_ptr[8*3] = (uint8)CLAMP(i);
|
|
208
|
+
|
|
209
|
+
i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3);
|
|
210
|
+
pDst_ptr[8*4] = (uint8)CLAMP(i);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
template <>
|
|
215
|
+
struct Col<1>
|
|
216
|
+
{
|
|
217
|
+
static void idct(uint8* pDst_ptr, const int* pTemp)
|
|
218
|
+
{
|
|
219
|
+
int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3);
|
|
220
|
+
const uint8 dcval_clamped = (uint8)CLAMP(dcval);
|
|
221
|
+
pDst_ptr[0*8] = dcval_clamped;
|
|
222
|
+
pDst_ptr[1*8] = dcval_clamped;
|
|
223
|
+
pDst_ptr[2*8] = dcval_clamped;
|
|
224
|
+
pDst_ptr[3*8] = dcval_clamped;
|
|
225
|
+
pDst_ptr[4*8] = dcval_clamped;
|
|
226
|
+
pDst_ptr[5*8] = dcval_clamped;
|
|
227
|
+
pDst_ptr[6*8] = dcval_clamped;
|
|
228
|
+
pDst_ptr[7*8] = dcval_clamped;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
static const uint8 s_idct_row_table[] =
|
|
233
|
+
{
|
|
234
|
+
1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,
|
|
235
|
+
4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,
|
|
236
|
+
6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,
|
|
237
|
+
6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,
|
|
238
|
+
8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,
|
|
239
|
+
8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,
|
|
240
|
+
8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,
|
|
241
|
+
8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
static const uint8 s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
|
|
245
|
+
|
|
246
|
+
void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag)
|
|
247
|
+
{
|
|
248
|
+
JPGD_ASSERT(block_max_zag >= 1);
|
|
249
|
+
JPGD_ASSERT(block_max_zag <= 64);
|
|
250
|
+
|
|
251
|
+
if (block_max_zag <= 1)
|
|
252
|
+
{
|
|
253
|
+
int k = ((pSrc_ptr[0] + 4) >> 3) + 128;
|
|
254
|
+
k = CLAMP(k);
|
|
255
|
+
k = k | (k<<8);
|
|
256
|
+
k = k | (k<<16);
|
|
257
|
+
|
|
258
|
+
for (int i = 8; i > 0; i--)
|
|
259
|
+
{
|
|
260
|
+
*(int*)&pDst_ptr[0] = k;
|
|
261
|
+
*(int*)&pDst_ptr[4] = k;
|
|
262
|
+
pDst_ptr += 8;
|
|
263
|
+
}
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
int temp[64];
|
|
268
|
+
|
|
269
|
+
const jpgd_block_t* pSrc = pSrc_ptr;
|
|
270
|
+
int* pTemp = temp;
|
|
271
|
+
|
|
272
|
+
const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];
|
|
273
|
+
int i;
|
|
274
|
+
for (i = 8; i > 0; i--, pRow_tab++)
|
|
275
|
+
{
|
|
276
|
+
switch (*pRow_tab)
|
|
277
|
+
{
|
|
278
|
+
case 0: Row<0>::idct(pTemp, pSrc); break;
|
|
279
|
+
case 1: Row<1>::idct(pTemp, pSrc); break;
|
|
280
|
+
case 2: Row<2>::idct(pTemp, pSrc); break;
|
|
281
|
+
case 3: Row<3>::idct(pTemp, pSrc); break;
|
|
282
|
+
case 4: Row<4>::idct(pTemp, pSrc); break;
|
|
283
|
+
case 5: Row<5>::idct(pTemp, pSrc); break;
|
|
284
|
+
case 6: Row<6>::idct(pTemp, pSrc); break;
|
|
285
|
+
case 7: Row<7>::idct(pTemp, pSrc); break;
|
|
286
|
+
case 8: Row<8>::idct(pTemp, pSrc); break;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
pSrc += 8;
|
|
290
|
+
pTemp += 8;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
pTemp = temp;
|
|
294
|
+
|
|
295
|
+
const int nonzero_rows = s_idct_col_table[block_max_zag - 1];
|
|
296
|
+
for (i = 8; i > 0; i--)
|
|
297
|
+
{
|
|
298
|
+
switch (nonzero_rows)
|
|
299
|
+
{
|
|
300
|
+
case 1: Col<1>::idct(pDst_ptr, pTemp); break;
|
|
301
|
+
case 2: Col<2>::idct(pDst_ptr, pTemp); break;
|
|
302
|
+
case 3: Col<3>::idct(pDst_ptr, pTemp); break;
|
|
303
|
+
case 4: Col<4>::idct(pDst_ptr, pTemp); break;
|
|
304
|
+
case 5: Col<5>::idct(pDst_ptr, pTemp); break;
|
|
305
|
+
case 6: Col<6>::idct(pDst_ptr, pTemp); break;
|
|
306
|
+
case 7: Col<7>::idct(pDst_ptr, pTemp); break;
|
|
307
|
+
case 8: Col<8>::idct(pDst_ptr, pTemp); break;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
pTemp++;
|
|
311
|
+
pDst_ptr++;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr)
|
|
316
|
+
{
|
|
317
|
+
int temp[64];
|
|
318
|
+
int* pTemp = temp;
|
|
319
|
+
const jpgd_block_t* pSrc = pSrc_ptr;
|
|
320
|
+
|
|
321
|
+
for (int i = 4; i > 0; i--)
|
|
322
|
+
{
|
|
323
|
+
Row<4>::idct(pTemp, pSrc);
|
|
324
|
+
pSrc += 8;
|
|
325
|
+
pTemp += 8;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
pTemp = temp;
|
|
329
|
+
for (int i = 8; i > 0; i--)
|
|
330
|
+
{
|
|
331
|
+
Col<4>::idct(pDst_ptr, pTemp);
|
|
332
|
+
pTemp++;
|
|
333
|
+
pDst_ptr++;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Retrieve one character from the input stream.
|
|
338
|
+
inline uint jpeg_decoder::get_char()
|
|
339
|
+
{
|
|
340
|
+
// Any bytes remaining in buffer?
|
|
341
|
+
if (!m_in_buf_left)
|
|
342
|
+
{
|
|
343
|
+
// Try to get more bytes.
|
|
344
|
+
prep_in_buffer();
|
|
345
|
+
// Still nothing to get?
|
|
346
|
+
if (!m_in_buf_left)
|
|
347
|
+
{
|
|
348
|
+
// Pad the end of the stream with 0xFF 0xD9 (EOI marker)
|
|
349
|
+
int t = m_tem_flag;
|
|
350
|
+
m_tem_flag ^= 1;
|
|
351
|
+
if (t)
|
|
352
|
+
return 0xD9;
|
|
353
|
+
else
|
|
354
|
+
return 0xFF;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
uint c = *m_pIn_buf_ofs++;
|
|
359
|
+
m_in_buf_left--;
|
|
360
|
+
|
|
361
|
+
return c;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Same as previous method, except can indicate if the character is a pad character or not.
|
|
365
|
+
inline uint jpeg_decoder::get_char(bool *pPadding_flag)
|
|
366
|
+
{
|
|
367
|
+
if (!m_in_buf_left)
|
|
368
|
+
{
|
|
369
|
+
prep_in_buffer();
|
|
370
|
+
if (!m_in_buf_left)
|
|
371
|
+
{
|
|
372
|
+
*pPadding_flag = true;
|
|
373
|
+
int t = m_tem_flag;
|
|
374
|
+
m_tem_flag ^= 1;
|
|
375
|
+
if (t)
|
|
376
|
+
return 0xD9;
|
|
377
|
+
else
|
|
378
|
+
return 0xFF;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
*pPadding_flag = false;
|
|
383
|
+
|
|
384
|
+
uint c = *m_pIn_buf_ofs++;
|
|
385
|
+
m_in_buf_left--;
|
|
386
|
+
|
|
387
|
+
return c;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Inserts a previously retrieved character back into the input buffer.
|
|
391
|
+
inline void jpeg_decoder::stuff_char(uint8 q)
|
|
392
|
+
{
|
|
393
|
+
*(--m_pIn_buf_ofs) = q;
|
|
394
|
+
m_in_buf_left++;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.
|
|
398
|
+
inline uint8 jpeg_decoder::get_octet()
|
|
399
|
+
{
|
|
400
|
+
bool padding_flag;
|
|
401
|
+
int c = get_char(&padding_flag);
|
|
402
|
+
|
|
403
|
+
if (c == 0xFF)
|
|
404
|
+
{
|
|
405
|
+
if (padding_flag)
|
|
406
|
+
return 0xFF;
|
|
407
|
+
|
|
408
|
+
c = get_char(&padding_flag);
|
|
409
|
+
if (padding_flag)
|
|
410
|
+
{
|
|
411
|
+
stuff_char(0xFF);
|
|
412
|
+
return 0xFF;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (c == 0x00)
|
|
416
|
+
return 0xFF;
|
|
417
|
+
else
|
|
418
|
+
{
|
|
419
|
+
stuff_char(static_cast<uint8>(c));
|
|
420
|
+
stuff_char(0xFF);
|
|
421
|
+
return 0xFF;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return static_cast<uint8>(c);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Retrieves a variable number of bits from the input stream. Does not recognize markers.
|
|
429
|
+
inline uint jpeg_decoder::get_bits(int num_bits)
|
|
430
|
+
{
|
|
431
|
+
if (!num_bits)
|
|
432
|
+
return 0;
|
|
433
|
+
|
|
434
|
+
uint i = m_bit_buf >> (32 - num_bits);
|
|
435
|
+
|
|
436
|
+
if ((m_bits_left -= num_bits) <= 0)
|
|
437
|
+
{
|
|
438
|
+
m_bit_buf <<= (num_bits += m_bits_left);
|
|
439
|
+
|
|
440
|
+
uint c1 = get_char();
|
|
441
|
+
uint c2 = get_char();
|
|
442
|
+
m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;
|
|
443
|
+
|
|
444
|
+
m_bit_buf <<= -m_bits_left;
|
|
445
|
+
|
|
446
|
+
m_bits_left += 16;
|
|
447
|
+
|
|
448
|
+
JPGD_ASSERT(m_bits_left >= 0);
|
|
449
|
+
}
|
|
450
|
+
else
|
|
451
|
+
m_bit_buf <<= num_bits;
|
|
452
|
+
|
|
453
|
+
return i;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered.
|
|
457
|
+
inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
|
|
458
|
+
{
|
|
459
|
+
if (!num_bits)
|
|
460
|
+
return 0;
|
|
461
|
+
|
|
462
|
+
uint i = m_bit_buf >> (32 - num_bits);
|
|
463
|
+
|
|
464
|
+
if ((m_bits_left -= num_bits) <= 0)
|
|
465
|
+
{
|
|
466
|
+
m_bit_buf <<= (num_bits += m_bits_left);
|
|
467
|
+
|
|
468
|
+
if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))
|
|
469
|
+
{
|
|
470
|
+
uint c1 = get_octet();
|
|
471
|
+
uint c2 = get_octet();
|
|
472
|
+
m_bit_buf |= (c1 << 8) | c2;
|
|
473
|
+
}
|
|
474
|
+
else
|
|
475
|
+
{
|
|
476
|
+
m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];
|
|
477
|
+
m_in_buf_left -= 2;
|
|
478
|
+
m_pIn_buf_ofs += 2;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
m_bit_buf <<= -m_bits_left;
|
|
482
|
+
|
|
483
|
+
m_bits_left += 16;
|
|
484
|
+
|
|
485
|
+
JPGD_ASSERT(m_bits_left >= 0);
|
|
486
|
+
}
|
|
487
|
+
else
|
|
488
|
+
m_bit_buf <<= num_bits;
|
|
489
|
+
|
|
490
|
+
return i;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Decodes a Huffman encoded symbol.
|
|
494
|
+
inline int jpeg_decoder::huff_decode(huff_tables *pH)
|
|
495
|
+
{
|
|
496
|
+
int symbol;
|
|
497
|
+
|
|
498
|
+
// Check first 8-bits: do we have a complete symbol?
|
|
499
|
+
if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
|
|
500
|
+
{
|
|
501
|
+
// Decode more bits, use a tree traversal to find symbol.
|
|
502
|
+
int ofs = 23;
|
|
503
|
+
do
|
|
504
|
+
{
|
|
505
|
+
symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
|
|
506
|
+
ofs--;
|
|
507
|
+
} while (symbol < 0);
|
|
508
|
+
|
|
509
|
+
get_bits_no_markers(8 + (23 - ofs));
|
|
510
|
+
}
|
|
511
|
+
else
|
|
512
|
+
get_bits_no_markers(pH->code_size[symbol]);
|
|
513
|
+
|
|
514
|
+
return symbol;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Decodes a Huffman encoded symbol.
|
|
518
|
+
inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
|
|
519
|
+
{
|
|
520
|
+
int symbol;
|
|
521
|
+
|
|
522
|
+
// Check first 8-bits: do we have a complete symbol?
|
|
523
|
+
if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
|
|
524
|
+
{
|
|
525
|
+
// Use a tree traversal to find symbol.
|
|
526
|
+
int ofs = 23;
|
|
527
|
+
do
|
|
528
|
+
{
|
|
529
|
+
symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
|
|
530
|
+
ofs--;
|
|
531
|
+
} while (symbol < 0);
|
|
532
|
+
|
|
533
|
+
get_bits_no_markers(8 + (23 - ofs));
|
|
534
|
+
|
|
535
|
+
extra_bits = get_bits_no_markers(symbol & 0xF);
|
|
536
|
+
}
|
|
537
|
+
else
|
|
538
|
+
{
|
|
539
|
+
JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0));
|
|
540
|
+
|
|
541
|
+
if (symbol & 0x8000)
|
|
542
|
+
{
|
|
543
|
+
get_bits_no_markers((symbol >> 8) & 31);
|
|
544
|
+
extra_bits = symbol >> 16;
|
|
545
|
+
}
|
|
546
|
+
else
|
|
547
|
+
{
|
|
548
|
+
int code_size = (symbol >> 8) & 31;
|
|
549
|
+
int num_extra_bits = symbol & 0xF;
|
|
550
|
+
int bits = code_size + num_extra_bits;
|
|
551
|
+
if (bits <= (m_bits_left + 16))
|
|
552
|
+
extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);
|
|
553
|
+
else
|
|
554
|
+
{
|
|
555
|
+
get_bits_no_markers(code_size);
|
|
556
|
+
extra_bits = get_bits_no_markers(num_extra_bits);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
symbol &= 0xFF;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return symbol;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// Tables and macro used to fully decode the DPCM differences.
|
|
567
|
+
static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
|
|
568
|
+
static const int s_extend_offset[16] = { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
|
|
569
|
+
static const int s_extend_mask[] = { 0, (1<<0), (1<<1), (1<<2), (1<<3), (1<<4), (1<<5), (1<<6), (1<<7), (1<<8), (1<<9), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15), (1<<16) };
|
|
570
|
+
// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this)
|
|
571
|
+
#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x))
|
|
572
|
+
|
|
573
|
+
// Clamps a value between 0-255.
|
|
574
|
+
inline uint8 jpeg_decoder::clamp(int i)
|
|
575
|
+
{
|
|
576
|
+
if (static_cast<uint>(i) > 255)
|
|
577
|
+
i = (((~i) >> 31) & 0xFF);
|
|
578
|
+
|
|
579
|
+
return static_cast<uint8>(i);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
namespace DCT_Upsample
|
|
583
|
+
{
|
|
584
|
+
struct Matrix44
|
|
585
|
+
{
|
|
586
|
+
typedef int Element_Type;
|
|
587
|
+
enum { NUM_ROWS = 4, NUM_COLS = 4 };
|
|
588
|
+
|
|
589
|
+
Element_Type v[NUM_ROWS][NUM_COLS];
|
|
590
|
+
|
|
591
|
+
inline int rows() const { return NUM_ROWS; }
|
|
592
|
+
inline int cols() const { return NUM_COLS; }
|
|
593
|
+
|
|
594
|
+
inline const Element_Type & at(int r, int c) const { return v[r][c]; }
|
|
595
|
+
inline Element_Type & at(int r, int c) { return v[r][c]; }
|
|
596
|
+
|
|
597
|
+
inline Matrix44() { }
|
|
598
|
+
|
|
599
|
+
inline Matrix44& operator += (const Matrix44& a)
|
|
600
|
+
{
|
|
601
|
+
for (int r = 0; r < NUM_ROWS; r++)
|
|
602
|
+
{
|
|
603
|
+
at(r, 0) += a.at(r, 0);
|
|
604
|
+
at(r, 1) += a.at(r, 1);
|
|
605
|
+
at(r, 2) += a.at(r, 2);
|
|
606
|
+
at(r, 3) += a.at(r, 3);
|
|
607
|
+
}
|
|
608
|
+
return *this;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
inline Matrix44& operator -= (const Matrix44& a)
|
|
612
|
+
{
|
|
613
|
+
for (int r = 0; r < NUM_ROWS; r++)
|
|
614
|
+
{
|
|
615
|
+
at(r, 0) -= a.at(r, 0);
|
|
616
|
+
at(r, 1) -= a.at(r, 1);
|
|
617
|
+
at(r, 2) -= a.at(r, 2);
|
|
618
|
+
at(r, 3) -= a.at(r, 3);
|
|
619
|
+
}
|
|
620
|
+
return *this;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b)
|
|
624
|
+
{
|
|
625
|
+
Matrix44 ret;
|
|
626
|
+
for (int r = 0; r < NUM_ROWS; r++)
|
|
627
|
+
{
|
|
628
|
+
ret.at(r, 0) = a.at(r, 0) + b.at(r, 0);
|
|
629
|
+
ret.at(r, 1) = a.at(r, 1) + b.at(r, 1);
|
|
630
|
+
ret.at(r, 2) = a.at(r, 2) + b.at(r, 2);
|
|
631
|
+
ret.at(r, 3) = a.at(r, 3) + b.at(r, 3);
|
|
632
|
+
}
|
|
633
|
+
return ret;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b)
|
|
637
|
+
{
|
|
638
|
+
Matrix44 ret;
|
|
639
|
+
for (int r = 0; r < NUM_ROWS; r++)
|
|
640
|
+
{
|
|
641
|
+
ret.at(r, 0) = a.at(r, 0) - b.at(r, 0);
|
|
642
|
+
ret.at(r, 1) = a.at(r, 1) - b.at(r, 1);
|
|
643
|
+
ret.at(r, 2) = a.at(r, 2) - b.at(r, 2);
|
|
644
|
+
ret.at(r, 3) = a.at(r, 3) - b.at(r, 3);
|
|
645
|
+
}
|
|
646
|
+
return ret;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b)
|
|
650
|
+
{
|
|
651
|
+
for (int r = 0; r < 4; r++)
|
|
652
|
+
{
|
|
653
|
+
pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) + b.at(r, 0));
|
|
654
|
+
pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) + b.at(r, 1));
|
|
655
|
+
pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) + b.at(r, 2));
|
|
656
|
+
pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) + b.at(r, 3));
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b)
|
|
661
|
+
{
|
|
662
|
+
for (int r = 0; r < 4; r++)
|
|
663
|
+
{
|
|
664
|
+
pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) - b.at(r, 0));
|
|
665
|
+
pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) - b.at(r, 1));
|
|
666
|
+
pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) - b.at(r, 2));
|
|
667
|
+
pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) - b.at(r, 3));
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
const int FRACT_BITS = 10;
|
|
673
|
+
const int SCALE = 1 << FRACT_BITS;
|
|
674
|
+
|
|
675
|
+
typedef int Temp_Type;
|
|
676
|
+
#define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS)
|
|
677
|
+
#define F(i) ((int)((i) * SCALE + .5f))
|
|
678
|
+
|
|
679
|
+
// Any decent C++ compiler will optimize this at compile time to a 0, or an array access.
|
|
680
|
+
#define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8])
|
|
681
|
+
|
|
682
|
+
// NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix
|
|
683
|
+
template<int NUM_ROWS, int NUM_COLS>
|
|
684
|
+
struct P_Q
|
|
685
|
+
{
|
|
686
|
+
static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc)
|
|
687
|
+
{
|
|
688
|
+
// 4x8 = 4x8 times 8x8, matrix 0 is constant
|
|
689
|
+
const Temp_Type X000 = AT(0, 0);
|
|
690
|
+
const Temp_Type X001 = AT(0, 1);
|
|
691
|
+
const Temp_Type X002 = AT(0, 2);
|
|
692
|
+
const Temp_Type X003 = AT(0, 3);
|
|
693
|
+
const Temp_Type X004 = AT(0, 4);
|
|
694
|
+
const Temp_Type X005 = AT(0, 5);
|
|
695
|
+
const Temp_Type X006 = AT(0, 6);
|
|
696
|
+
const Temp_Type X007 = AT(0, 7);
|
|
697
|
+
const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0));
|
|
698
|
+
const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1));
|
|
699
|
+
const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2));
|
|
700
|
+
const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3));
|
|
701
|
+
const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4));
|
|
702
|
+
const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5));
|
|
703
|
+
const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6));
|
|
704
|
+
const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7));
|
|
705
|
+
const Temp_Type X020 = AT(4, 0);
|
|
706
|
+
const Temp_Type X021 = AT(4, 1);
|
|
707
|
+
const Temp_Type X022 = AT(4, 2);
|
|
708
|
+
const Temp_Type X023 = AT(4, 3);
|
|
709
|
+
const Temp_Type X024 = AT(4, 4);
|
|
710
|
+
const Temp_Type X025 = AT(4, 5);
|
|
711
|
+
const Temp_Type X026 = AT(4, 6);
|
|
712
|
+
const Temp_Type X027 = AT(4, 7);
|
|
713
|
+
const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0));
|
|
714
|
+
const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1));
|
|
715
|
+
const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2));
|
|
716
|
+
const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3));
|
|
717
|
+
const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4));
|
|
718
|
+
const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5));
|
|
719
|
+
const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6));
|
|
720
|
+
const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7));
|
|
721
|
+
|
|
722
|
+
// 4x4 = 4x8 times 8x4, matrix 1 is constant
|
|
723
|
+
P.at(0, 0) = X000;
|
|
724
|
+
P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f));
|
|
725
|
+
P.at(0, 2) = X004;
|
|
726
|
+
P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f));
|
|
727
|
+
P.at(1, 0) = X010;
|
|
728
|
+
P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f));
|
|
729
|
+
P.at(1, 2) = X014;
|
|
730
|
+
P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f));
|
|
731
|
+
P.at(2, 0) = X020;
|
|
732
|
+
P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f));
|
|
733
|
+
P.at(2, 2) = X024;
|
|
734
|
+
P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f));
|
|
735
|
+
P.at(3, 0) = X030;
|
|
736
|
+
P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f));
|
|
737
|
+
P.at(3, 2) = X034;
|
|
738
|
+
P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f));
|
|
739
|
+
// 40 muls 24 adds
|
|
740
|
+
|
|
741
|
+
// 4x4 = 4x8 times 8x4, matrix 1 is constant
|
|
742
|
+
Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f));
|
|
743
|
+
Q.at(0, 1) = X002;
|
|
744
|
+
Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f));
|
|
745
|
+
Q.at(0, 3) = X006;
|
|
746
|
+
Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f));
|
|
747
|
+
Q.at(1, 1) = X012;
|
|
748
|
+
Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f));
|
|
749
|
+
Q.at(1, 3) = X016;
|
|
750
|
+
Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f));
|
|
751
|
+
Q.at(2, 1) = X022;
|
|
752
|
+
Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f));
|
|
753
|
+
Q.at(2, 3) = X026;
|
|
754
|
+
Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f));
|
|
755
|
+
Q.at(3, 1) = X032;
|
|
756
|
+
Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f));
|
|
757
|
+
Q.at(3, 3) = X036;
|
|
758
|
+
// 40 muls 24 adds
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
template<int NUM_ROWS, int NUM_COLS>
|
|
763
|
+
struct R_S
|
|
764
|
+
{
|
|
765
|
+
static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc)
|
|
766
|
+
{
|
|
767
|
+
// 4x8 = 4x8 times 8x8, matrix 0 is constant
|
|
768
|
+
const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0));
|
|
769
|
+
const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1));
|
|
770
|
+
const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2));
|
|
771
|
+
const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3));
|
|
772
|
+
const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4));
|
|
773
|
+
const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5));
|
|
774
|
+
const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6));
|
|
775
|
+
const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7));
|
|
776
|
+
const Temp_Type X110 = AT(2, 0);
|
|
777
|
+
const Temp_Type X111 = AT(2, 1);
|
|
778
|
+
const Temp_Type X112 = AT(2, 2);
|
|
779
|
+
const Temp_Type X113 = AT(2, 3);
|
|
780
|
+
const Temp_Type X114 = AT(2, 4);
|
|
781
|
+
const Temp_Type X115 = AT(2, 5);
|
|
782
|
+
const Temp_Type X116 = AT(2, 6);
|
|
783
|
+
const Temp_Type X117 = AT(2, 7);
|
|
784
|
+
const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0));
|
|
785
|
+
const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1));
|
|
786
|
+
const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2));
|
|
787
|
+
const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3));
|
|
788
|
+
const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4));
|
|
789
|
+
const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5));
|
|
790
|
+
const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6));
|
|
791
|
+
const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7));
|
|
792
|
+
const Temp_Type X130 = AT(6, 0);
|
|
793
|
+
const Temp_Type X131 = AT(6, 1);
|
|
794
|
+
const Temp_Type X132 = AT(6, 2);
|
|
795
|
+
const Temp_Type X133 = AT(6, 3);
|
|
796
|
+
const Temp_Type X134 = AT(6, 4);
|
|
797
|
+
const Temp_Type X135 = AT(6, 5);
|
|
798
|
+
const Temp_Type X136 = AT(6, 6);
|
|
799
|
+
const Temp_Type X137 = AT(6, 7);
|
|
800
|
+
// 80 muls 48 adds
|
|
801
|
+
|
|
802
|
+
// 4x4 = 4x8 times 8x4, matrix 1 is constant
|
|
803
|
+
R.at(0, 0) = X100;
|
|
804
|
+
R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f));
|
|
805
|
+
R.at(0, 2) = X104;
|
|
806
|
+
R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f));
|
|
807
|
+
R.at(1, 0) = X110;
|
|
808
|
+
R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f));
|
|
809
|
+
R.at(1, 2) = X114;
|
|
810
|
+
R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f));
|
|
811
|
+
R.at(2, 0) = X120;
|
|
812
|
+
R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f));
|
|
813
|
+
R.at(2, 2) = X124;
|
|
814
|
+
R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f));
|
|
815
|
+
R.at(3, 0) = X130;
|
|
816
|
+
R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f));
|
|
817
|
+
R.at(3, 2) = X134;
|
|
818
|
+
R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f));
|
|
819
|
+
// 40 muls 24 adds
|
|
820
|
+
// 4x4 = 4x8 times 8x4, matrix 1 is constant
|
|
821
|
+
S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f));
|
|
822
|
+
S.at(0, 1) = X102;
|
|
823
|
+
S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f));
|
|
824
|
+
S.at(0, 3) = X106;
|
|
825
|
+
S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f));
|
|
826
|
+
S.at(1, 1) = X112;
|
|
827
|
+
S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f));
|
|
828
|
+
S.at(1, 3) = X116;
|
|
829
|
+
S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f));
|
|
830
|
+
S.at(2, 1) = X122;
|
|
831
|
+
S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f));
|
|
832
|
+
S.at(2, 3) = X126;
|
|
833
|
+
S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f));
|
|
834
|
+
S.at(3, 1) = X132;
|
|
835
|
+
S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f));
|
|
836
|
+
S.at(3, 3) = X136;
|
|
837
|
+
// 40 muls 24 adds
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
} // end namespace DCT_Upsample
|
|
841
|
+
|
|
842
|
+
// Unconditionally frees all allocated m_blocks.
|
|
843
|
+
void jpeg_decoder::free_all_blocks()
|
|
844
|
+
{
|
|
845
|
+
m_pStream = NULL;
|
|
846
|
+
for (mem_block *b = m_pMem_blocks; b; )
|
|
847
|
+
{
|
|
848
|
+
mem_block *n = b->m_pNext;
|
|
849
|
+
jpgd_free(b);
|
|
850
|
+
b = n;
|
|
851
|
+
}
|
|
852
|
+
m_pMem_blocks = NULL;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// This method handles all errors. It will never return.
|
|
856
|
+
// It could easily be changed to use C++ exceptions.
|
|
857
|
+
JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)
|
|
858
|
+
{
|
|
859
|
+
m_error_code = status;
|
|
860
|
+
free_all_blocks();
|
|
861
|
+
longjmp(m_jmp_state, status);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
void *jpeg_decoder::alloc(size_t nSize, bool zero)
|
|
865
|
+
{
|
|
866
|
+
nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;
|
|
867
|
+
char *rv = NULL;
|
|
868
|
+
for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext)
|
|
869
|
+
{
|
|
870
|
+
if ((b->m_used_count + nSize) <= b->m_size)
|
|
871
|
+
{
|
|
872
|
+
rv = b->m_data + b->m_used_count;
|
|
873
|
+
b->m_used_count += nSize;
|
|
874
|
+
break;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
if (!rv)
|
|
878
|
+
{
|
|
879
|
+
int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047);
|
|
880
|
+
mem_block *b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);
|
|
881
|
+
if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); }
|
|
882
|
+
b->m_pNext = m_pMem_blocks; m_pMem_blocks = b;
|
|
883
|
+
b->m_used_count = nSize;
|
|
884
|
+
b->m_size = capacity;
|
|
885
|
+
rv = b->m_data;
|
|
886
|
+
}
|
|
887
|
+
if (zero) memset(rv, 0, nSize);
|
|
888
|
+
return rv;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
void jpeg_decoder::word_clear(void *p, uint16 c, uint n)
|
|
892
|
+
{
|
|
893
|
+
uint8 *pD = (uint8*)p;
|
|
894
|
+
const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;
|
|
895
|
+
while (n)
|
|
896
|
+
{
|
|
897
|
+
pD[0] = l; pD[1] = h; pD += 2;
|
|
898
|
+
n--;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// Refill the input buffer.
|
|
903
|
+
// This method will sit in a loop until (A) the buffer is full or (B)
|
|
904
|
+
// the stream's read() method reports and end of file condition.
|
|
905
|
+
void jpeg_decoder::prep_in_buffer()
|
|
906
|
+
{
|
|
907
|
+
m_in_buf_left = 0;
|
|
908
|
+
m_pIn_buf_ofs = m_in_buf;
|
|
909
|
+
|
|
910
|
+
if (m_eof_flag)
|
|
911
|
+
return;
|
|
912
|
+
|
|
913
|
+
do
|
|
914
|
+
{
|
|
915
|
+
int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);
|
|
916
|
+
if (bytes_read == -1)
|
|
917
|
+
stop_decoding(JPGD_STREAM_READ);
|
|
918
|
+
|
|
919
|
+
m_in_buf_left += bytes_read;
|
|
920
|
+
} while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));
|
|
921
|
+
|
|
922
|
+
m_total_bytes_read += m_in_buf_left;
|
|
923
|
+
|
|
924
|
+
// Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).
|
|
925
|
+
// (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.)
|
|
926
|
+
word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// Read a Huffman code table.
|
|
930
|
+
void jpeg_decoder::read_dht_marker()
|
|
931
|
+
{
|
|
932
|
+
int i, index, count;
|
|
933
|
+
uint8 huff_num[17];
|
|
934
|
+
uint8 huff_val[256];
|
|
935
|
+
|
|
936
|
+
uint num_left = get_bits(16);
|
|
937
|
+
|
|
938
|
+
if (num_left < 2)
|
|
939
|
+
stop_decoding(JPGD_BAD_DHT_MARKER);
|
|
940
|
+
|
|
941
|
+
num_left -= 2;
|
|
942
|
+
|
|
943
|
+
while (num_left)
|
|
944
|
+
{
|
|
945
|
+
index = get_bits(8);
|
|
946
|
+
|
|
947
|
+
huff_num[0] = 0;
|
|
948
|
+
|
|
949
|
+
count = 0;
|
|
950
|
+
|
|
951
|
+
for (i = 1; i <= 16; i++)
|
|
952
|
+
{
|
|
953
|
+
huff_num[i] = static_cast<uint8>(get_bits(8));
|
|
954
|
+
count += huff_num[i];
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
if (count > 255)
|
|
958
|
+
stop_decoding(JPGD_BAD_DHT_COUNTS);
|
|
959
|
+
|
|
960
|
+
for (i = 0; i < count; i++)
|
|
961
|
+
huff_val[i] = static_cast<uint8>(get_bits(8));
|
|
962
|
+
|
|
963
|
+
i = 1 + 16 + count;
|
|
964
|
+
|
|
965
|
+
if (num_left < (uint)i)
|
|
966
|
+
stop_decoding(JPGD_BAD_DHT_MARKER);
|
|
967
|
+
|
|
968
|
+
num_left -= i;
|
|
969
|
+
|
|
970
|
+
if ((index & 0x10) > 0x10)
|
|
971
|
+
stop_decoding(JPGD_BAD_DHT_INDEX);
|
|
972
|
+
|
|
973
|
+
index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);
|
|
974
|
+
|
|
975
|
+
if (index >= JPGD_MAX_HUFF_TABLES)
|
|
976
|
+
stop_decoding(JPGD_BAD_DHT_INDEX);
|
|
977
|
+
|
|
978
|
+
if (!m_huff_num[index])
|
|
979
|
+
m_huff_num[index] = (uint8 *)alloc(17);
|
|
980
|
+
|
|
981
|
+
if (!m_huff_val[index])
|
|
982
|
+
m_huff_val[index] = (uint8 *)alloc(256);
|
|
983
|
+
|
|
984
|
+
m_huff_ac[index] = (index & 0x10) != 0;
|
|
985
|
+
memcpy(m_huff_num[index], huff_num, 17);
|
|
986
|
+
memcpy(m_huff_val[index], huff_val, 256);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// Read a quantization table.
|
|
991
|
+
void jpeg_decoder::read_dqt_marker()
|
|
992
|
+
{
|
|
993
|
+
int n, i, prec;
|
|
994
|
+
uint num_left;
|
|
995
|
+
uint temp;
|
|
996
|
+
|
|
997
|
+
num_left = get_bits(16);
|
|
998
|
+
|
|
999
|
+
if (num_left < 2)
|
|
1000
|
+
stop_decoding(JPGD_BAD_DQT_MARKER);
|
|
1001
|
+
|
|
1002
|
+
num_left -= 2;
|
|
1003
|
+
|
|
1004
|
+
while (num_left)
|
|
1005
|
+
{
|
|
1006
|
+
n = get_bits(8);
|
|
1007
|
+
prec = n >> 4;
|
|
1008
|
+
n &= 0x0F;
|
|
1009
|
+
|
|
1010
|
+
if (n >= JPGD_MAX_QUANT_TABLES)
|
|
1011
|
+
stop_decoding(JPGD_BAD_DQT_TABLE);
|
|
1012
|
+
|
|
1013
|
+
if (!m_quant[n])
|
|
1014
|
+
m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t));
|
|
1015
|
+
|
|
1016
|
+
// read quantization entries, in zag order
|
|
1017
|
+
for (i = 0; i < 64; i++)
|
|
1018
|
+
{
|
|
1019
|
+
temp = get_bits(8);
|
|
1020
|
+
|
|
1021
|
+
if (prec)
|
|
1022
|
+
temp = (temp << 8) + get_bits(8);
|
|
1023
|
+
|
|
1024
|
+
m_quant[n][i] = static_cast<jpgd_quant_t>(temp);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
i = 64 + 1;
|
|
1028
|
+
|
|
1029
|
+
if (prec)
|
|
1030
|
+
i += 64;
|
|
1031
|
+
|
|
1032
|
+
if (num_left < (uint)i)
|
|
1033
|
+
stop_decoding(JPGD_BAD_DQT_LENGTH);
|
|
1034
|
+
|
|
1035
|
+
num_left -= i;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// Read the start of frame (SOF) marker.
|
|
1040
|
+
void jpeg_decoder::read_sof_marker()
|
|
1041
|
+
{
|
|
1042
|
+
int i;
|
|
1043
|
+
uint num_left;
|
|
1044
|
+
|
|
1045
|
+
num_left = get_bits(16);
|
|
1046
|
+
|
|
1047
|
+
if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */
|
|
1048
|
+
stop_decoding(JPGD_BAD_PRECISION);
|
|
1049
|
+
|
|
1050
|
+
m_image_y_size = get_bits(16);
|
|
1051
|
+
|
|
1052
|
+
if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))
|
|
1053
|
+
stop_decoding(JPGD_BAD_HEIGHT);
|
|
1054
|
+
|
|
1055
|
+
m_image_x_size = get_bits(16);
|
|
1056
|
+
|
|
1057
|
+
if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))
|
|
1058
|
+
stop_decoding(JPGD_BAD_WIDTH);
|
|
1059
|
+
|
|
1060
|
+
m_comps_in_frame = get_bits(8);
|
|
1061
|
+
|
|
1062
|
+
if (m_comps_in_frame > JPGD_MAX_COMPONENTS)
|
|
1063
|
+
stop_decoding(JPGD_TOO_MANY_COMPONENTS);
|
|
1064
|
+
|
|
1065
|
+
if (num_left != (uint)(m_comps_in_frame * 3 + 8))
|
|
1066
|
+
stop_decoding(JPGD_BAD_SOF_LENGTH);
|
|
1067
|
+
|
|
1068
|
+
for (i = 0; i < m_comps_in_frame; i++)
|
|
1069
|
+
{
|
|
1070
|
+
m_comp_ident[i] = get_bits(8);
|
|
1071
|
+
m_comp_h_samp[i] = get_bits(4);
|
|
1072
|
+
m_comp_v_samp[i] = get_bits(4);
|
|
1073
|
+
m_comp_quant[i] = get_bits(8);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// Used to skip unrecognized markers.
|
|
1078
|
+
void jpeg_decoder::skip_variable_marker()
|
|
1079
|
+
{
|
|
1080
|
+
uint num_left;
|
|
1081
|
+
|
|
1082
|
+
num_left = get_bits(16);
|
|
1083
|
+
|
|
1084
|
+
if (num_left < 2)
|
|
1085
|
+
stop_decoding(JPGD_BAD_VARIABLE_MARKER);
|
|
1086
|
+
|
|
1087
|
+
num_left -= 2;
|
|
1088
|
+
|
|
1089
|
+
while (num_left)
|
|
1090
|
+
{
|
|
1091
|
+
get_bits(8);
|
|
1092
|
+
num_left--;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// Read a define restart interval (DRI) marker.
|
|
1097
|
+
void jpeg_decoder::read_dri_marker()
|
|
1098
|
+
{
|
|
1099
|
+
if (get_bits(16) != 4)
|
|
1100
|
+
stop_decoding(JPGD_BAD_DRI_LENGTH);
|
|
1101
|
+
|
|
1102
|
+
m_restart_interval = get_bits(16);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// Read a start of scan (SOS) marker.
|
|
1106
|
+
void jpeg_decoder::read_sos_marker()
|
|
1107
|
+
{
|
|
1108
|
+
uint num_left;
|
|
1109
|
+
int i, ci, n, c, cc;
|
|
1110
|
+
|
|
1111
|
+
num_left = get_bits(16);
|
|
1112
|
+
|
|
1113
|
+
n = get_bits(8);
|
|
1114
|
+
|
|
1115
|
+
m_comps_in_scan = n;
|
|
1116
|
+
|
|
1117
|
+
num_left -= 3;
|
|
1118
|
+
|
|
1119
|
+
if ( (num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) )
|
|
1120
|
+
stop_decoding(JPGD_BAD_SOS_LENGTH);
|
|
1121
|
+
|
|
1122
|
+
for (i = 0; i < n; i++)
|
|
1123
|
+
{
|
|
1124
|
+
cc = get_bits(8);
|
|
1125
|
+
c = get_bits(8);
|
|
1126
|
+
num_left -= 2;
|
|
1127
|
+
|
|
1128
|
+
for (ci = 0; ci < m_comps_in_frame; ci++)
|
|
1129
|
+
if (cc == m_comp_ident[ci])
|
|
1130
|
+
break;
|
|
1131
|
+
|
|
1132
|
+
if (ci >= m_comps_in_frame)
|
|
1133
|
+
stop_decoding(JPGD_BAD_SOS_COMP_ID);
|
|
1134
|
+
|
|
1135
|
+
m_comp_list[i] = ci;
|
|
1136
|
+
m_comp_dc_tab[ci] = (c >> 4) & 15;
|
|
1137
|
+
m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
m_spectral_start = get_bits(8);
|
|
1141
|
+
m_spectral_end = get_bits(8);
|
|
1142
|
+
m_successive_high = get_bits(4);
|
|
1143
|
+
m_successive_low = get_bits(4);
|
|
1144
|
+
|
|
1145
|
+
if (!m_progressive_flag)
|
|
1146
|
+
{
|
|
1147
|
+
m_spectral_start = 0;
|
|
1148
|
+
m_spectral_end = 63;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
num_left -= 3;
|
|
1152
|
+
|
|
1153
|
+
while (num_left) /* read past whatever is num_left */
|
|
1154
|
+
{
|
|
1155
|
+
get_bits(8);
|
|
1156
|
+
num_left--;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// Finds the next marker.
|
|
1161
|
+
int jpeg_decoder::next_marker()
|
|
1162
|
+
{
|
|
1163
|
+
uint c, bytes;
|
|
1164
|
+
|
|
1165
|
+
bytes = 0;
|
|
1166
|
+
|
|
1167
|
+
do
|
|
1168
|
+
{
|
|
1169
|
+
do
|
|
1170
|
+
{
|
|
1171
|
+
bytes++;
|
|
1172
|
+
c = get_bits(8);
|
|
1173
|
+
} while (c != 0xFF);
|
|
1174
|
+
|
|
1175
|
+
do
|
|
1176
|
+
{
|
|
1177
|
+
c = get_bits(8);
|
|
1178
|
+
} while (c == 0xFF);
|
|
1179
|
+
|
|
1180
|
+
} while (c == 0);
|
|
1181
|
+
|
|
1182
|
+
// If bytes > 0 here, there where extra bytes before the marker (not good).
|
|
1183
|
+
|
|
1184
|
+
return c;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
|
|
1188
|
+
// encountered.
|
|
1189
|
+
int jpeg_decoder::process_markers()
|
|
1190
|
+
{
|
|
1191
|
+
int c;
|
|
1192
|
+
|
|
1193
|
+
for ( ; ; )
|
|
1194
|
+
{
|
|
1195
|
+
c = next_marker();
|
|
1196
|
+
|
|
1197
|
+
switch (c)
|
|
1198
|
+
{
|
|
1199
|
+
case M_SOF0:
|
|
1200
|
+
case M_SOF1:
|
|
1201
|
+
case M_SOF2:
|
|
1202
|
+
case M_SOF3:
|
|
1203
|
+
case M_SOF5:
|
|
1204
|
+
case M_SOF6:
|
|
1205
|
+
case M_SOF7:
|
|
1206
|
+
// case M_JPG:
|
|
1207
|
+
case M_SOF9:
|
|
1208
|
+
case M_SOF10:
|
|
1209
|
+
case M_SOF11:
|
|
1210
|
+
case M_SOF13:
|
|
1211
|
+
case M_SOF14:
|
|
1212
|
+
case M_SOF15:
|
|
1213
|
+
case M_SOI:
|
|
1214
|
+
case M_EOI:
|
|
1215
|
+
case M_SOS:
|
|
1216
|
+
{
|
|
1217
|
+
return c;
|
|
1218
|
+
}
|
|
1219
|
+
case M_DHT:
|
|
1220
|
+
{
|
|
1221
|
+
read_dht_marker();
|
|
1222
|
+
break;
|
|
1223
|
+
}
|
|
1224
|
+
// No arithmitic support - dumb patents!
|
|
1225
|
+
case M_DAC:
|
|
1226
|
+
{
|
|
1227
|
+
stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
|
|
1228
|
+
break;
|
|
1229
|
+
}
|
|
1230
|
+
case M_DQT:
|
|
1231
|
+
{
|
|
1232
|
+
read_dqt_marker();
|
|
1233
|
+
break;
|
|
1234
|
+
}
|
|
1235
|
+
case M_DRI:
|
|
1236
|
+
{
|
|
1237
|
+
read_dri_marker();
|
|
1238
|
+
break;
|
|
1239
|
+
}
|
|
1240
|
+
//case M_APP0: /* no need to read the JFIF marker */
|
|
1241
|
+
|
|
1242
|
+
case M_JPG:
|
|
1243
|
+
case M_RST0: /* no parameters */
|
|
1244
|
+
case M_RST1:
|
|
1245
|
+
case M_RST2:
|
|
1246
|
+
case M_RST3:
|
|
1247
|
+
case M_RST4:
|
|
1248
|
+
case M_RST5:
|
|
1249
|
+
case M_RST6:
|
|
1250
|
+
case M_RST7:
|
|
1251
|
+
case M_TEM:
|
|
1252
|
+
{
|
|
1253
|
+
stop_decoding(JPGD_UNEXPECTED_MARKER);
|
|
1254
|
+
break;
|
|
1255
|
+
}
|
|
1256
|
+
default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
|
|
1257
|
+
{
|
|
1258
|
+
skip_variable_marker();
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// Finds the start of image (SOI) marker.
|
|
1266
|
+
// This code is rather defensive: it only checks the first 512 bytes to avoid
|
|
1267
|
+
// false positives.
|
|
1268
|
+
void jpeg_decoder::locate_soi_marker()
|
|
1269
|
+
{
|
|
1270
|
+
uint lastchar, thischar;
|
|
1271
|
+
uint bytesleft;
|
|
1272
|
+
|
|
1273
|
+
lastchar = get_bits(8);
|
|
1274
|
+
|
|
1275
|
+
thischar = get_bits(8);
|
|
1276
|
+
|
|
1277
|
+
/* ok if it's a normal JPEG file without a special header */
|
|
1278
|
+
|
|
1279
|
+
if ((lastchar == 0xFF) && (thischar == M_SOI))
|
|
1280
|
+
return;
|
|
1281
|
+
|
|
1282
|
+
bytesleft = 4096; //512;
|
|
1283
|
+
|
|
1284
|
+
for ( ; ; )
|
|
1285
|
+
{
|
|
1286
|
+
if (--bytesleft == 0)
|
|
1287
|
+
stop_decoding(JPGD_NOT_JPEG);
|
|
1288
|
+
|
|
1289
|
+
lastchar = thischar;
|
|
1290
|
+
|
|
1291
|
+
thischar = get_bits(8);
|
|
1292
|
+
|
|
1293
|
+
if (lastchar == 0xFF)
|
|
1294
|
+
{
|
|
1295
|
+
if (thischar == M_SOI)
|
|
1296
|
+
break;
|
|
1297
|
+
else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end
|
|
1298
|
+
stop_decoding(JPGD_NOT_JPEG);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad.
|
|
1303
|
+
thischar = (m_bit_buf >> 24) & 0xFF;
|
|
1304
|
+
|
|
1305
|
+
if (thischar != 0xFF)
|
|
1306
|
+
stop_decoding(JPGD_NOT_JPEG);
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
// Find a start of frame (SOF) marker.
|
|
1310
|
+
void jpeg_decoder::locate_sof_marker()
|
|
1311
|
+
{
|
|
1312
|
+
locate_soi_marker();
|
|
1313
|
+
|
|
1314
|
+
int c = process_markers();
|
|
1315
|
+
|
|
1316
|
+
switch (c)
|
|
1317
|
+
{
|
|
1318
|
+
case M_SOF2:
|
|
1319
|
+
m_progressive_flag = JPGD_TRUE;
|
|
1320
|
+
case M_SOF0: /* baseline DCT */
|
|
1321
|
+
case M_SOF1: /* extended sequential DCT */
|
|
1322
|
+
{
|
|
1323
|
+
read_sof_marker();
|
|
1324
|
+
break;
|
|
1325
|
+
}
|
|
1326
|
+
case M_SOF9: /* Arithmitic coding */
|
|
1327
|
+
{
|
|
1328
|
+
stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
|
|
1329
|
+
break;
|
|
1330
|
+
}
|
|
1331
|
+
default:
|
|
1332
|
+
{
|
|
1333
|
+
stop_decoding(JPGD_UNSUPPORTED_MARKER);
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
// Find a start of scan (SOS) marker.
|
|
1340
|
+
int jpeg_decoder::locate_sos_marker()
|
|
1341
|
+
{
|
|
1342
|
+
int c;
|
|
1343
|
+
|
|
1344
|
+
c = process_markers();
|
|
1345
|
+
|
|
1346
|
+
if (c == M_EOI)
|
|
1347
|
+
return JPGD_FALSE;
|
|
1348
|
+
else if (c != M_SOS)
|
|
1349
|
+
stop_decoding(JPGD_UNEXPECTED_MARKER);
|
|
1350
|
+
|
|
1351
|
+
read_sos_marker();
|
|
1352
|
+
|
|
1353
|
+
return JPGD_TRUE;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// Reset everything to default/uninitialized state.
|
|
1357
|
+
void jpeg_decoder::init(jpeg_decoder_stream *pStream)
|
|
1358
|
+
{
|
|
1359
|
+
m_pMem_blocks = NULL;
|
|
1360
|
+
m_error_code = JPGD_SUCCESS;
|
|
1361
|
+
m_ready_flag = false;
|
|
1362
|
+
m_image_x_size = m_image_y_size = 0;
|
|
1363
|
+
m_pStream = pStream;
|
|
1364
|
+
m_progressive_flag = JPGD_FALSE;
|
|
1365
|
+
|
|
1366
|
+
memset(m_huff_ac, 0, sizeof(m_huff_ac));
|
|
1367
|
+
memset(m_huff_num, 0, sizeof(m_huff_num));
|
|
1368
|
+
memset(m_huff_val, 0, sizeof(m_huff_val));
|
|
1369
|
+
memset(m_quant, 0, sizeof(m_quant));
|
|
1370
|
+
|
|
1371
|
+
m_scan_type = 0;
|
|
1372
|
+
m_comps_in_frame = 0;
|
|
1373
|
+
|
|
1374
|
+
memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));
|
|
1375
|
+
memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));
|
|
1376
|
+
memset(m_comp_quant, 0, sizeof(m_comp_quant));
|
|
1377
|
+
memset(m_comp_ident, 0, sizeof(m_comp_ident));
|
|
1378
|
+
memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));
|
|
1379
|
+
memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));
|
|
1380
|
+
|
|
1381
|
+
m_comps_in_scan = 0;
|
|
1382
|
+
memset(m_comp_list, 0, sizeof(m_comp_list));
|
|
1383
|
+
memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));
|
|
1384
|
+
memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));
|
|
1385
|
+
|
|
1386
|
+
m_spectral_start = 0;
|
|
1387
|
+
m_spectral_end = 0;
|
|
1388
|
+
m_successive_low = 0;
|
|
1389
|
+
m_successive_high = 0;
|
|
1390
|
+
m_max_mcu_x_size = 0;
|
|
1391
|
+
m_max_mcu_y_size = 0;
|
|
1392
|
+
m_blocks_per_mcu = 0;
|
|
1393
|
+
m_max_blocks_per_row = 0;
|
|
1394
|
+
m_mcus_per_row = 0;
|
|
1395
|
+
m_mcus_per_col = 0;
|
|
1396
|
+
m_expanded_blocks_per_component = 0;
|
|
1397
|
+
m_expanded_blocks_per_mcu = 0;
|
|
1398
|
+
m_expanded_blocks_per_row = 0;
|
|
1399
|
+
m_freq_domain_chroma_upsample = false;
|
|
1400
|
+
|
|
1401
|
+
memset(m_mcu_org, 0, sizeof(m_mcu_org));
|
|
1402
|
+
|
|
1403
|
+
m_total_lines_left = 0;
|
|
1404
|
+
m_mcu_lines_left = 0;
|
|
1405
|
+
m_real_dest_bytes_per_scan_line = 0;
|
|
1406
|
+
m_dest_bytes_per_scan_line = 0;
|
|
1407
|
+
m_dest_bytes_per_pixel = 0;
|
|
1408
|
+
|
|
1409
|
+
memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));
|
|
1410
|
+
|
|
1411
|
+
memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));
|
|
1412
|
+
memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));
|
|
1413
|
+
memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
|
|
1414
|
+
|
|
1415
|
+
m_eob_run = 0;
|
|
1416
|
+
|
|
1417
|
+
memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
|
|
1418
|
+
|
|
1419
|
+
m_pIn_buf_ofs = m_in_buf;
|
|
1420
|
+
m_in_buf_left = 0;
|
|
1421
|
+
m_eof_flag = false;
|
|
1422
|
+
m_tem_flag = 0;
|
|
1423
|
+
|
|
1424
|
+
memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));
|
|
1425
|
+
memset(m_in_buf, 0, sizeof(m_in_buf));
|
|
1426
|
+
memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));
|
|
1427
|
+
|
|
1428
|
+
m_restart_interval = 0;
|
|
1429
|
+
m_restarts_left = 0;
|
|
1430
|
+
m_next_restart_num = 0;
|
|
1431
|
+
|
|
1432
|
+
m_max_mcus_per_row = 0;
|
|
1433
|
+
m_max_blocks_per_mcu = 0;
|
|
1434
|
+
m_max_mcus_per_col = 0;
|
|
1435
|
+
|
|
1436
|
+
memset(m_last_dc_val, 0, sizeof(m_last_dc_val));
|
|
1437
|
+
m_pMCU_coefficients = NULL;
|
|
1438
|
+
m_pSample_buf = NULL;
|
|
1439
|
+
|
|
1440
|
+
m_total_bytes_read = 0;
|
|
1441
|
+
|
|
1442
|
+
m_pScan_line_0 = NULL;
|
|
1443
|
+
m_pScan_line_1 = NULL;
|
|
1444
|
+
|
|
1445
|
+
// Ready the input buffer.
|
|
1446
|
+
prep_in_buffer();
|
|
1447
|
+
|
|
1448
|
+
// Prime the bit buffer.
|
|
1449
|
+
m_bits_left = 16;
|
|
1450
|
+
m_bit_buf = 0;
|
|
1451
|
+
|
|
1452
|
+
get_bits(16);
|
|
1453
|
+
get_bits(16);
|
|
1454
|
+
|
|
1455
|
+
for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)
|
|
1456
|
+
m_mcu_block_max_zag[i] = 64;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
#define SCALEBITS 16
|
|
1460
|
+
#define ONE_HALF ((int) 1 << (SCALEBITS-1))
|
|
1461
|
+
#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f))
|
|
1462
|
+
|
|
1463
|
+
// Create a few tables that allow us to quickly convert YCbCr to RGB.
|
|
1464
|
+
void jpeg_decoder::create_look_ups()
|
|
1465
|
+
{
|
|
1466
|
+
for (int i = 0; i <= 255; i++)
|
|
1467
|
+
{
|
|
1468
|
+
int k = i - 128;
|
|
1469
|
+
m_crr[i] = ( FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;
|
|
1470
|
+
m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;
|
|
1471
|
+
m_crg[i] = (-FIX(0.71414f)) * k;
|
|
1472
|
+
m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
// This method throws back into the stream any bytes that where read
|
|
1477
|
+
// into the bit buffer during initial marker scanning.
|
|
1478
|
+
void jpeg_decoder::fix_in_buffer()
|
|
1479
|
+
{
|
|
1480
|
+
// In case any 0xFF's where pulled into the buffer during marker scanning.
|
|
1481
|
+
JPGD_ASSERT((m_bits_left & 7) == 0);
|
|
1482
|
+
|
|
1483
|
+
if (m_bits_left == 16)
|
|
1484
|
+
stuff_char( (uint8)(m_bit_buf & 0xFF));
|
|
1485
|
+
|
|
1486
|
+
if (m_bits_left >= 8)
|
|
1487
|
+
stuff_char( (uint8)((m_bit_buf >> 8) & 0xFF));
|
|
1488
|
+
|
|
1489
|
+
stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));
|
|
1490
|
+
stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));
|
|
1491
|
+
|
|
1492
|
+
m_bits_left = 16;
|
|
1493
|
+
get_bits_no_markers(16);
|
|
1494
|
+
get_bits_no_markers(16);
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
void jpeg_decoder::transform_mcu(int mcu_row)
|
|
1498
|
+
{
|
|
1499
|
+
jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
|
|
1500
|
+
uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
|
|
1501
|
+
|
|
1502
|
+
for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
|
|
1503
|
+
{
|
|
1504
|
+
idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);
|
|
1505
|
+
pSrc_ptr += 64;
|
|
1506
|
+
pDst_ptr += 64;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
static const uint8 s_max_rc[64] =
|
|
1511
|
+
{
|
|
1512
|
+
17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86,
|
|
1513
|
+
102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136,
|
|
1514
|
+
136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
|
|
1515
|
+
136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136
|
|
1516
|
+
};
|
|
1517
|
+
|
|
1518
|
+
void jpeg_decoder::transform_mcu_expand(int mcu_row)
|
|
1519
|
+
{
|
|
1520
|
+
jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
|
|
1521
|
+
uint8* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64;
|
|
1522
|
+
|
|
1523
|
+
// Y IDCT
|
|
1524
|
+
int mcu_block;
|
|
1525
|
+
for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++)
|
|
1526
|
+
{
|
|
1527
|
+
idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);
|
|
1528
|
+
pSrc_ptr += 64;
|
|
1529
|
+
pDst_ptr += 64;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
// Chroma IDCT, with upsampling
|
|
1533
|
+
jpgd_block_t temp_block[64];
|
|
1534
|
+
|
|
1535
|
+
for (int i = 0; i < 2; i++)
|
|
1536
|
+
{
|
|
1537
|
+
DCT_Upsample::Matrix44 P, Q, R, S;
|
|
1538
|
+
|
|
1539
|
+
JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1);
|
|
1540
|
+
JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64);
|
|
1541
|
+
|
|
1542
|
+
int max_zag = m_mcu_block_max_zag[mcu_block++] - 1;
|
|
1543
|
+
if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis
|
|
1544
|
+
switch (s_max_rc[max_zag])
|
|
1545
|
+
{
|
|
1546
|
+
case 1*16+1:
|
|
1547
|
+
DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr);
|
|
1548
|
+
DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr);
|
|
1549
|
+
break;
|
|
1550
|
+
case 1*16+2:
|
|
1551
|
+
DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr);
|
|
1552
|
+
DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr);
|
|
1553
|
+
break;
|
|
1554
|
+
case 2*16+2:
|
|
1555
|
+
DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr);
|
|
1556
|
+
DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr);
|
|
1557
|
+
break;
|
|
1558
|
+
case 3*16+2:
|
|
1559
|
+
DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr);
|
|
1560
|
+
DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr);
|
|
1561
|
+
break;
|
|
1562
|
+
case 3*16+3:
|
|
1563
|
+
DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr);
|
|
1564
|
+
DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr);
|
|
1565
|
+
break;
|
|
1566
|
+
case 3*16+4:
|
|
1567
|
+
DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr);
|
|
1568
|
+
DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr);
|
|
1569
|
+
break;
|
|
1570
|
+
case 4*16+4:
|
|
1571
|
+
DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr);
|
|
1572
|
+
DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr);
|
|
1573
|
+
break;
|
|
1574
|
+
case 5*16+4:
|
|
1575
|
+
DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr);
|
|
1576
|
+
DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr);
|
|
1577
|
+
break;
|
|
1578
|
+
case 5*16+5:
|
|
1579
|
+
DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr);
|
|
1580
|
+
DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr);
|
|
1581
|
+
break;
|
|
1582
|
+
case 5*16+6:
|
|
1583
|
+
DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr);
|
|
1584
|
+
DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr);
|
|
1585
|
+
break;
|
|
1586
|
+
case 6*16+6:
|
|
1587
|
+
DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr);
|
|
1588
|
+
DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr);
|
|
1589
|
+
break;
|
|
1590
|
+
case 7*16+6:
|
|
1591
|
+
DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr);
|
|
1592
|
+
DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr);
|
|
1593
|
+
break;
|
|
1594
|
+
case 7*16+7:
|
|
1595
|
+
DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr);
|
|
1596
|
+
DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr);
|
|
1597
|
+
break;
|
|
1598
|
+
case 7*16+8:
|
|
1599
|
+
DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr);
|
|
1600
|
+
DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr);
|
|
1601
|
+
break;
|
|
1602
|
+
case 8*16+8:
|
|
1603
|
+
DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr);
|
|
1604
|
+
DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr);
|
|
1605
|
+
break;
|
|
1606
|
+
default:
|
|
1607
|
+
JPGD_ASSERT(false);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
DCT_Upsample::Matrix44 a(P + Q); P -= Q;
|
|
1611
|
+
DCT_Upsample::Matrix44& b = P;
|
|
1612
|
+
DCT_Upsample::Matrix44 c(R + S); R -= S;
|
|
1613
|
+
DCT_Upsample::Matrix44& d = R;
|
|
1614
|
+
|
|
1615
|
+
DCT_Upsample::Matrix44::add_and_store(temp_block, a, c);
|
|
1616
|
+
idct_4x4(temp_block, pDst_ptr);
|
|
1617
|
+
pDst_ptr += 64;
|
|
1618
|
+
|
|
1619
|
+
DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c);
|
|
1620
|
+
idct_4x4(temp_block, pDst_ptr);
|
|
1621
|
+
pDst_ptr += 64;
|
|
1622
|
+
|
|
1623
|
+
DCT_Upsample::Matrix44::add_and_store(temp_block, b, d);
|
|
1624
|
+
idct_4x4(temp_block, pDst_ptr);
|
|
1625
|
+
pDst_ptr += 64;
|
|
1626
|
+
|
|
1627
|
+
DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d);
|
|
1628
|
+
idct_4x4(temp_block, pDst_ptr);
|
|
1629
|
+
pDst_ptr += 64;
|
|
1630
|
+
|
|
1631
|
+
pSrc_ptr += 64;
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// Loads and dequantizes the next row of (already decoded) coefficients.
|
|
1636
|
+
// Progressive images only.
|
|
1637
|
+
void jpeg_decoder::load_next_row()
|
|
1638
|
+
{
|
|
1639
|
+
int i;
|
|
1640
|
+
jpgd_block_t *p;
|
|
1641
|
+
jpgd_quant_t *q;
|
|
1642
|
+
int mcu_row, mcu_block, row_block = 0;
|
|
1643
|
+
int component_num, component_id;
|
|
1644
|
+
int block_x_mcu[JPGD_MAX_COMPONENTS];
|
|
1645
|
+
|
|
1646
|
+
memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));
|
|
1647
|
+
|
|
1648
|
+
for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
|
|
1649
|
+
{
|
|
1650
|
+
int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
|
|
1651
|
+
|
|
1652
|
+
for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
|
|
1653
|
+
{
|
|
1654
|
+
component_id = m_mcu_org[mcu_block];
|
|
1655
|
+
q = m_quant[m_comp_quant[component_id]];
|
|
1656
|
+
|
|
1657
|
+
p = m_pMCU_coefficients + 64 * mcu_block;
|
|
1658
|
+
|
|
1659
|
+
jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
|
|
1660
|
+
jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
|
|
1661
|
+
p[0] = pDC[0];
|
|
1662
|
+
memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t));
|
|
1663
|
+
|
|
1664
|
+
for (i = 63; i > 0; i--)
|
|
1665
|
+
if (p[g_ZAG[i]])
|
|
1666
|
+
break;
|
|
1667
|
+
|
|
1668
|
+
m_mcu_block_max_zag[mcu_block] = i + 1;
|
|
1669
|
+
|
|
1670
|
+
for ( ; i >= 0; i--)
|
|
1671
|
+
if (p[g_ZAG[i]])
|
|
1672
|
+
p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]);
|
|
1673
|
+
|
|
1674
|
+
row_block++;
|
|
1675
|
+
|
|
1676
|
+
if (m_comps_in_scan == 1)
|
|
1677
|
+
block_x_mcu[component_id]++;
|
|
1678
|
+
else
|
|
1679
|
+
{
|
|
1680
|
+
if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
|
|
1681
|
+
{
|
|
1682
|
+
block_x_mcu_ofs = 0;
|
|
1683
|
+
|
|
1684
|
+
if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
|
|
1685
|
+
{
|
|
1686
|
+
block_y_mcu_ofs = 0;
|
|
1687
|
+
|
|
1688
|
+
block_x_mcu[component_id] += m_comp_h_samp[component_id];
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
if (m_freq_domain_chroma_upsample)
|
|
1695
|
+
transform_mcu_expand(mcu_row);
|
|
1696
|
+
else
|
|
1697
|
+
transform_mcu(mcu_row);
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
if (m_comps_in_scan == 1)
|
|
1701
|
+
m_block_y_mcu[m_comp_list[0]]++;
|
|
1702
|
+
else
|
|
1703
|
+
{
|
|
1704
|
+
for (component_num = 0; component_num < m_comps_in_scan; component_num++)
|
|
1705
|
+
{
|
|
1706
|
+
component_id = m_comp_list[component_num];
|
|
1707
|
+
|
|
1708
|
+
m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
// Restart interval processing.
|
|
1714
|
+
void jpeg_decoder::process_restart()
|
|
1715
|
+
{
|
|
1716
|
+
int i;
|
|
1717
|
+
int c = 0;
|
|
1718
|
+
|
|
1719
|
+
// Align to a byte boundry
|
|
1720
|
+
// FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!
|
|
1721
|
+
//get_bits_no_markers(m_bits_left & 7);
|
|
1722
|
+
|
|
1723
|
+
// Let's scan a little bit to find the marker, but not _too_ far.
|
|
1724
|
+
// 1536 is a "fudge factor" that determines how much to scan.
|
|
1725
|
+
for (i = 1536; i > 0; i--)
|
|
1726
|
+
if (get_char() == 0xFF)
|
|
1727
|
+
break;
|
|
1728
|
+
|
|
1729
|
+
if (i == 0)
|
|
1730
|
+
stop_decoding(JPGD_BAD_RESTART_MARKER);
|
|
1731
|
+
|
|
1732
|
+
for ( ; i > 0; i--)
|
|
1733
|
+
if ((c = get_char()) != 0xFF)
|
|
1734
|
+
break;
|
|
1735
|
+
|
|
1736
|
+
if (i == 0)
|
|
1737
|
+
stop_decoding(JPGD_BAD_RESTART_MARKER);
|
|
1738
|
+
|
|
1739
|
+
// Is it the expected marker? If not, something bad happened.
|
|
1740
|
+
if (c != (m_next_restart_num + M_RST0))
|
|
1741
|
+
stop_decoding(JPGD_BAD_RESTART_MARKER);
|
|
1742
|
+
|
|
1743
|
+
// Reset each component's DC prediction values.
|
|
1744
|
+
memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
|
|
1745
|
+
|
|
1746
|
+
m_eob_run = 0;
|
|
1747
|
+
|
|
1748
|
+
m_restarts_left = m_restart_interval;
|
|
1749
|
+
|
|
1750
|
+
m_next_restart_num = (m_next_restart_num + 1) & 7;
|
|
1751
|
+
|
|
1752
|
+
// Get the bit buffer going again...
|
|
1753
|
+
|
|
1754
|
+
m_bits_left = 16;
|
|
1755
|
+
get_bits_no_markers(16);
|
|
1756
|
+
get_bits_no_markers(16);
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
static inline int dequantize_ac(int c, int q) { c *= q; return c; }
|
|
1760
|
+
|
|
1761
|
+
// Decodes and dequantizes the next row of coefficients.
|
|
1762
|
+
void jpeg_decoder::decode_next_row()
|
|
1763
|
+
{
|
|
1764
|
+
int row_block = 0;
|
|
1765
|
+
|
|
1766
|
+
for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
|
|
1767
|
+
{
|
|
1768
|
+
if ((m_restart_interval) && (m_restarts_left == 0))
|
|
1769
|
+
process_restart();
|
|
1770
|
+
|
|
1771
|
+
jpgd_block_t* p = m_pMCU_coefficients;
|
|
1772
|
+
for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
|
|
1773
|
+
{
|
|
1774
|
+
int component_id = m_mcu_org[mcu_block];
|
|
1775
|
+
jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
|
|
1776
|
+
|
|
1777
|
+
int r, s;
|
|
1778
|
+
s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);
|
|
1779
|
+
s = JPGD_HUFF_EXTEND(r, s);
|
|
1780
|
+
|
|
1781
|
+
m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);
|
|
1782
|
+
|
|
1783
|
+
p[0] = static_cast<jpgd_block_t>(s * q[0]);
|
|
1784
|
+
|
|
1785
|
+
int prev_num_set = m_mcu_block_max_zag[mcu_block];
|
|
1786
|
+
|
|
1787
|
+
huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];
|
|
1788
|
+
|
|
1789
|
+
int k;
|
|
1790
|
+
for (k = 1; k < 64; k++)
|
|
1791
|
+
{
|
|
1792
|
+
int extra_bits;
|
|
1793
|
+
s = huff_decode(pH, extra_bits);
|
|
1794
|
+
|
|
1795
|
+
r = s >> 4;
|
|
1796
|
+
s &= 15;
|
|
1797
|
+
|
|
1798
|
+
if (s)
|
|
1799
|
+
{
|
|
1800
|
+
if (r)
|
|
1801
|
+
{
|
|
1802
|
+
if ((k + r) > 63)
|
|
1803
|
+
stop_decoding(JPGD_DECODE_ERROR);
|
|
1804
|
+
|
|
1805
|
+
if (k < prev_num_set)
|
|
1806
|
+
{
|
|
1807
|
+
int n = JPGD_MIN(r, prev_num_set - k);
|
|
1808
|
+
int kt = k;
|
|
1809
|
+
while (n--)
|
|
1810
|
+
p[g_ZAG[kt++]] = 0;
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
k += r;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
s = JPGD_HUFF_EXTEND(extra_bits, s);
|
|
1817
|
+
|
|
1818
|
+
JPGD_ASSERT(k < 64);
|
|
1819
|
+
|
|
1820
|
+
p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k];
|
|
1821
|
+
}
|
|
1822
|
+
else
|
|
1823
|
+
{
|
|
1824
|
+
if (r == 15)
|
|
1825
|
+
{
|
|
1826
|
+
if ((k + 16) > 64)
|
|
1827
|
+
stop_decoding(JPGD_DECODE_ERROR);
|
|
1828
|
+
|
|
1829
|
+
if (k < prev_num_set)
|
|
1830
|
+
{
|
|
1831
|
+
int n = JPGD_MIN(16, prev_num_set - k);
|
|
1832
|
+
int kt = k;
|
|
1833
|
+
while (n--)
|
|
1834
|
+
{
|
|
1835
|
+
JPGD_ASSERT(kt <= 63);
|
|
1836
|
+
p[g_ZAG[kt++]] = 0;
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
k += 16 - 1; // - 1 because the loop counter is k
|
|
1841
|
+
JPGD_ASSERT(p[g_ZAG[k]] == 0);
|
|
1842
|
+
}
|
|
1843
|
+
else
|
|
1844
|
+
break;
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
if (k < prev_num_set)
|
|
1849
|
+
{
|
|
1850
|
+
int kt = k;
|
|
1851
|
+
while (kt < prev_num_set)
|
|
1852
|
+
p[g_ZAG[kt++]] = 0;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
m_mcu_block_max_zag[mcu_block] = k;
|
|
1856
|
+
|
|
1857
|
+
row_block++;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
if (m_freq_domain_chroma_upsample)
|
|
1861
|
+
transform_mcu_expand(mcu_row);
|
|
1862
|
+
else
|
|
1863
|
+
transform_mcu(mcu_row);
|
|
1864
|
+
|
|
1865
|
+
m_restarts_left--;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB
|
|
1870
|
+
void jpeg_decoder::H1V1Convert()
|
|
1871
|
+
{
|
|
1872
|
+
int row = m_max_mcu_y_size - m_mcu_lines_left;
|
|
1873
|
+
uint8 *d = m_pScan_line_0;
|
|
1874
|
+
uint8 *s = m_pSample_buf + row * 8;
|
|
1875
|
+
|
|
1876
|
+
for (int i = m_max_mcus_per_row; i > 0; i--)
|
|
1877
|
+
{
|
|
1878
|
+
for (int j = 0; j < 8; j++)
|
|
1879
|
+
{
|
|
1880
|
+
int y = s[j];
|
|
1881
|
+
int cb = s[64+j];
|
|
1882
|
+
int cr = s[128+j];
|
|
1883
|
+
|
|
1884
|
+
d[0] = clamp(y + m_crr[cr]);
|
|
1885
|
+
d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
|
|
1886
|
+
d[2] = clamp(y + m_cbb[cb]);
|
|
1887
|
+
d[3] = 255;
|
|
1888
|
+
|
|
1889
|
+
d += 4;
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
s += 64*3;
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
|
|
1897
|
+
void jpeg_decoder::H2V1Convert()
|
|
1898
|
+
{
|
|
1899
|
+
int row = m_max_mcu_y_size - m_mcu_lines_left;
|
|
1900
|
+
uint8 *d0 = m_pScan_line_0;
|
|
1901
|
+
uint8 *y = m_pSample_buf + row * 8;
|
|
1902
|
+
uint8 *c = m_pSample_buf + 2*64 + row * 8;
|
|
1903
|
+
|
|
1904
|
+
for (int i = m_max_mcus_per_row; i > 0; i--)
|
|
1905
|
+
{
|
|
1906
|
+
for (int l = 0; l < 2; l++)
|
|
1907
|
+
{
|
|
1908
|
+
for (int j = 0; j < 4; j++)
|
|
1909
|
+
{
|
|
1910
|
+
int cb = c[0];
|
|
1911
|
+
int cr = c[64];
|
|
1912
|
+
|
|
1913
|
+
int rc = m_crr[cr];
|
|
1914
|
+
int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
|
|
1915
|
+
int bc = m_cbb[cb];
|
|
1916
|
+
|
|
1917
|
+
int yy = y[j<<1];
|
|
1918
|
+
d0[0] = clamp(yy+rc);
|
|
1919
|
+
d0[1] = clamp(yy+gc);
|
|
1920
|
+
d0[2] = clamp(yy+bc);
|
|
1921
|
+
d0[3] = 255;
|
|
1922
|
+
|
|
1923
|
+
yy = y[(j<<1)+1];
|
|
1924
|
+
d0[4] = clamp(yy+rc);
|
|
1925
|
+
d0[5] = clamp(yy+gc);
|
|
1926
|
+
d0[6] = clamp(yy+bc);
|
|
1927
|
+
d0[7] = 255;
|
|
1928
|
+
|
|
1929
|
+
d0 += 8;
|
|
1930
|
+
|
|
1931
|
+
c++;
|
|
1932
|
+
}
|
|
1933
|
+
y += 64;
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
y += 64*4 - 64*2;
|
|
1937
|
+
c += 64*4 - 8;
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
|
|
1942
|
+
void jpeg_decoder::H1V2Convert()
|
|
1943
|
+
{
|
|
1944
|
+
int row = m_max_mcu_y_size - m_mcu_lines_left;
|
|
1945
|
+
uint8 *d0 = m_pScan_line_0;
|
|
1946
|
+
uint8 *d1 = m_pScan_line_1;
|
|
1947
|
+
uint8 *y;
|
|
1948
|
+
uint8 *c;
|
|
1949
|
+
|
|
1950
|
+
if (row < 8)
|
|
1951
|
+
y = m_pSample_buf + row * 8;
|
|
1952
|
+
else
|
|
1953
|
+
y = m_pSample_buf + 64*1 + (row & 7) * 8;
|
|
1954
|
+
|
|
1955
|
+
c = m_pSample_buf + 64*2 + (row >> 1) * 8;
|
|
1956
|
+
|
|
1957
|
+
for (int i = m_max_mcus_per_row; i > 0; i--)
|
|
1958
|
+
{
|
|
1959
|
+
for (int j = 0; j < 8; j++)
|
|
1960
|
+
{
|
|
1961
|
+
int cb = c[0+j];
|
|
1962
|
+
int cr = c[64+j];
|
|
1963
|
+
|
|
1964
|
+
int rc = m_crr[cr];
|
|
1965
|
+
int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
|
|
1966
|
+
int bc = m_cbb[cb];
|
|
1967
|
+
|
|
1968
|
+
int yy = y[j];
|
|
1969
|
+
d0[0] = clamp(yy+rc);
|
|
1970
|
+
d0[1] = clamp(yy+gc);
|
|
1971
|
+
d0[2] = clamp(yy+bc);
|
|
1972
|
+
d0[3] = 255;
|
|
1973
|
+
|
|
1974
|
+
yy = y[8+j];
|
|
1975
|
+
d1[0] = clamp(yy+rc);
|
|
1976
|
+
d1[1] = clamp(yy+gc);
|
|
1977
|
+
d1[2] = clamp(yy+bc);
|
|
1978
|
+
d1[3] = 255;
|
|
1979
|
+
|
|
1980
|
+
d0 += 4;
|
|
1981
|
+
d1 += 4;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
y += 64*4;
|
|
1985
|
+
c += 64*4;
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB
|
|
1990
|
+
void jpeg_decoder::H2V2Convert()
|
|
1991
|
+
{
|
|
1992
|
+
int row = m_max_mcu_y_size - m_mcu_lines_left;
|
|
1993
|
+
uint8 *d0 = m_pScan_line_0;
|
|
1994
|
+
uint8 *d1 = m_pScan_line_1;
|
|
1995
|
+
uint8 *y;
|
|
1996
|
+
uint8 *c;
|
|
1997
|
+
|
|
1998
|
+
if (row < 8)
|
|
1999
|
+
y = m_pSample_buf + row * 8;
|
|
2000
|
+
else
|
|
2001
|
+
y = m_pSample_buf + 64*2 + (row & 7) * 8;
|
|
2002
|
+
|
|
2003
|
+
c = m_pSample_buf + 64*4 + (row >> 1) * 8;
|
|
2004
|
+
|
|
2005
|
+
for (int i = m_max_mcus_per_row; i > 0; i--)
|
|
2006
|
+
{
|
|
2007
|
+
for (int l = 0; l < 2; l++)
|
|
2008
|
+
{
|
|
2009
|
+
for (int j = 0; j < 8; j += 2)
|
|
2010
|
+
{
|
|
2011
|
+
int cb = c[0];
|
|
2012
|
+
int cr = c[64];
|
|
2013
|
+
|
|
2014
|
+
int rc = m_crr[cr];
|
|
2015
|
+
int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
|
|
2016
|
+
int bc = m_cbb[cb];
|
|
2017
|
+
|
|
2018
|
+
int yy = y[j];
|
|
2019
|
+
d0[0] = clamp(yy+rc);
|
|
2020
|
+
d0[1] = clamp(yy+gc);
|
|
2021
|
+
d0[2] = clamp(yy+bc);
|
|
2022
|
+
d0[3] = 255;
|
|
2023
|
+
|
|
2024
|
+
yy = y[j+1];
|
|
2025
|
+
d0[4] = clamp(yy+rc);
|
|
2026
|
+
d0[5] = clamp(yy+gc);
|
|
2027
|
+
d0[6] = clamp(yy+bc);
|
|
2028
|
+
d0[7] = 255;
|
|
2029
|
+
|
|
2030
|
+
yy = y[j+8];
|
|
2031
|
+
d1[0] = clamp(yy+rc);
|
|
2032
|
+
d1[1] = clamp(yy+gc);
|
|
2033
|
+
d1[2] = clamp(yy+bc);
|
|
2034
|
+
d1[3] = 255;
|
|
2035
|
+
|
|
2036
|
+
yy = y[j+8+1];
|
|
2037
|
+
d1[4] = clamp(yy+rc);
|
|
2038
|
+
d1[5] = clamp(yy+gc);
|
|
2039
|
+
d1[6] = clamp(yy+bc);
|
|
2040
|
+
d1[7] = 255;
|
|
2041
|
+
|
|
2042
|
+
d0 += 8;
|
|
2043
|
+
d1 += 8;
|
|
2044
|
+
|
|
2045
|
+
c++;
|
|
2046
|
+
}
|
|
2047
|
+
y += 64;
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
y += 64*6 - 64*2;
|
|
2051
|
+
c += 64*6 - 8;
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// Y (1 block per MCU) to 8-bit grayscale
|
|
2056
|
+
void jpeg_decoder::gray_convert()
|
|
2057
|
+
{
|
|
2058
|
+
int row = m_max_mcu_y_size - m_mcu_lines_left;
|
|
2059
|
+
uint8 *d = m_pScan_line_0;
|
|
2060
|
+
uint8 *s = m_pSample_buf + row * 8;
|
|
2061
|
+
|
|
2062
|
+
for (int i = m_max_mcus_per_row; i > 0; i--)
|
|
2063
|
+
{
|
|
2064
|
+
*(uint *)d = *(uint *)s;
|
|
2065
|
+
*(uint *)(&d[4]) = *(uint *)(&s[4]);
|
|
2066
|
+
|
|
2067
|
+
s += 64;
|
|
2068
|
+
d += 8;
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
void jpeg_decoder::expanded_convert()
|
|
2073
|
+
{
|
|
2074
|
+
int row = m_max_mcu_y_size - m_mcu_lines_left;
|
|
2075
|
+
|
|
2076
|
+
uint8* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8;
|
|
2077
|
+
|
|
2078
|
+
uint8* d = m_pScan_line_0;
|
|
2079
|
+
|
|
2080
|
+
for (int i = m_max_mcus_per_row; i > 0; i--)
|
|
2081
|
+
{
|
|
2082
|
+
for (int k = 0; k < m_max_mcu_x_size; k += 8)
|
|
2083
|
+
{
|
|
2084
|
+
const int Y_ofs = k * 8;
|
|
2085
|
+
const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component;
|
|
2086
|
+
const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2;
|
|
2087
|
+
for (int j = 0; j < 8; j++)
|
|
2088
|
+
{
|
|
2089
|
+
int y = Py[Y_ofs + j];
|
|
2090
|
+
int cb = Py[Cb_ofs + j];
|
|
2091
|
+
int cr = Py[Cr_ofs + j];
|
|
2092
|
+
|
|
2093
|
+
d[0] = clamp(y + m_crr[cr]);
|
|
2094
|
+
d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
|
|
2095
|
+
d[2] = clamp(y + m_cbb[cb]);
|
|
2096
|
+
d[3] = 255;
|
|
2097
|
+
|
|
2098
|
+
d += 4;
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
Py += 64 * m_expanded_blocks_per_mcu;
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.
|
|
2107
|
+
void jpeg_decoder::find_eoi()
|
|
2108
|
+
{
|
|
2109
|
+
if (!m_progressive_flag)
|
|
2110
|
+
{
|
|
2111
|
+
// Attempt to read the EOI marker.
|
|
2112
|
+
//get_bits_no_markers(m_bits_left & 7);
|
|
2113
|
+
|
|
2114
|
+
// Prime the bit buffer
|
|
2115
|
+
m_bits_left = 16;
|
|
2116
|
+
get_bits(16);
|
|
2117
|
+
get_bits(16);
|
|
2118
|
+
|
|
2119
|
+
// The next marker _should_ be EOI
|
|
2120
|
+
process_markers();
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
m_total_bytes_read -= m_in_buf_left;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)
|
|
2127
|
+
{
|
|
2128
|
+
if ((m_error_code) || (!m_ready_flag))
|
|
2129
|
+
return JPGD_FAILED;
|
|
2130
|
+
|
|
2131
|
+
if (m_total_lines_left == 0)
|
|
2132
|
+
return JPGD_DONE;
|
|
2133
|
+
|
|
2134
|
+
if (m_mcu_lines_left == 0)
|
|
2135
|
+
{
|
|
2136
|
+
if (setjmp(m_jmp_state))
|
|
2137
|
+
return JPGD_FAILED;
|
|
2138
|
+
|
|
2139
|
+
if (m_progressive_flag)
|
|
2140
|
+
load_next_row();
|
|
2141
|
+
else
|
|
2142
|
+
decode_next_row();
|
|
2143
|
+
|
|
2144
|
+
// Find the EOI marker if that was the last row.
|
|
2145
|
+
if (m_total_lines_left <= m_max_mcu_y_size)
|
|
2146
|
+
find_eoi();
|
|
2147
|
+
|
|
2148
|
+
m_mcu_lines_left = m_max_mcu_y_size;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
if (m_freq_domain_chroma_upsample)
|
|
2152
|
+
{
|
|
2153
|
+
expanded_convert();
|
|
2154
|
+
*pScan_line = m_pScan_line_0;
|
|
2155
|
+
}
|
|
2156
|
+
else
|
|
2157
|
+
{
|
|
2158
|
+
switch (m_scan_type)
|
|
2159
|
+
{
|
|
2160
|
+
case JPGD_YH2V2:
|
|
2161
|
+
{
|
|
2162
|
+
if ((m_mcu_lines_left & 1) == 0)
|
|
2163
|
+
{
|
|
2164
|
+
H2V2Convert();
|
|
2165
|
+
*pScan_line = m_pScan_line_0;
|
|
2166
|
+
}
|
|
2167
|
+
else
|
|
2168
|
+
*pScan_line = m_pScan_line_1;
|
|
2169
|
+
|
|
2170
|
+
break;
|
|
2171
|
+
}
|
|
2172
|
+
case JPGD_YH2V1:
|
|
2173
|
+
{
|
|
2174
|
+
H2V1Convert();
|
|
2175
|
+
*pScan_line = m_pScan_line_0;
|
|
2176
|
+
break;
|
|
2177
|
+
}
|
|
2178
|
+
case JPGD_YH1V2:
|
|
2179
|
+
{
|
|
2180
|
+
if ((m_mcu_lines_left & 1) == 0)
|
|
2181
|
+
{
|
|
2182
|
+
H1V2Convert();
|
|
2183
|
+
*pScan_line = m_pScan_line_0;
|
|
2184
|
+
}
|
|
2185
|
+
else
|
|
2186
|
+
*pScan_line = m_pScan_line_1;
|
|
2187
|
+
|
|
2188
|
+
break;
|
|
2189
|
+
}
|
|
2190
|
+
case JPGD_YH1V1:
|
|
2191
|
+
{
|
|
2192
|
+
H1V1Convert();
|
|
2193
|
+
*pScan_line = m_pScan_line_0;
|
|
2194
|
+
break;
|
|
2195
|
+
}
|
|
2196
|
+
case JPGD_GRAYSCALE:
|
|
2197
|
+
{
|
|
2198
|
+
gray_convert();
|
|
2199
|
+
*pScan_line = m_pScan_line_0;
|
|
2200
|
+
|
|
2201
|
+
break;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
*pScan_line_len = m_real_dest_bytes_per_scan_line;
|
|
2207
|
+
|
|
2208
|
+
m_mcu_lines_left--;
|
|
2209
|
+
m_total_lines_left--;
|
|
2210
|
+
|
|
2211
|
+
return JPGD_SUCCESS;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
// Creates the tables needed for efficient Huffman decoding.
|
|
2215
|
+
void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
|
|
2216
|
+
{
|
|
2217
|
+
int p, i, l, si;
|
|
2218
|
+
uint8 huffsize[257];
|
|
2219
|
+
uint huffcode[257];
|
|
2220
|
+
uint code;
|
|
2221
|
+
uint subtree;
|
|
2222
|
+
int code_size;
|
|
2223
|
+
int lastp;
|
|
2224
|
+
int nextfreeentry;
|
|
2225
|
+
int currententry;
|
|
2226
|
+
|
|
2227
|
+
pH->ac_table = m_huff_ac[index] != 0;
|
|
2228
|
+
|
|
2229
|
+
p = 0;
|
|
2230
|
+
|
|
2231
|
+
for (l = 1; l <= 16; l++)
|
|
2232
|
+
{
|
|
2233
|
+
for (i = 1; i <= m_huff_num[index][l]; i++)
|
|
2234
|
+
huffsize[p++] = static_cast<uint8>(l);
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
huffsize[p] = 0;
|
|
2238
|
+
|
|
2239
|
+
lastp = p;
|
|
2240
|
+
|
|
2241
|
+
code = 0;
|
|
2242
|
+
si = huffsize[0];
|
|
2243
|
+
p = 0;
|
|
2244
|
+
|
|
2245
|
+
while (huffsize[p])
|
|
2246
|
+
{
|
|
2247
|
+
while (huffsize[p] == si)
|
|
2248
|
+
{
|
|
2249
|
+
huffcode[p++] = code;
|
|
2250
|
+
code++;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
code <<= 1;
|
|
2254
|
+
si++;
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
memset(pH->look_up, 0, sizeof(pH->look_up));
|
|
2258
|
+
memset(pH->look_up2, 0, sizeof(pH->look_up2));
|
|
2259
|
+
memset(pH->tree, 0, sizeof(pH->tree));
|
|
2260
|
+
memset(pH->code_size, 0, sizeof(pH->code_size));
|
|
2261
|
+
|
|
2262
|
+
nextfreeentry = -1;
|
|
2263
|
+
|
|
2264
|
+
p = 0;
|
|
2265
|
+
|
|
2266
|
+
while (p < lastp)
|
|
2267
|
+
{
|
|
2268
|
+
i = m_huff_val[index][p];
|
|
2269
|
+
code = huffcode[p];
|
|
2270
|
+
code_size = huffsize[p];
|
|
2271
|
+
|
|
2272
|
+
pH->code_size[i] = static_cast<uint8>(code_size);
|
|
2273
|
+
|
|
2274
|
+
if (code_size <= 8)
|
|
2275
|
+
{
|
|
2276
|
+
code <<= (8 - code_size);
|
|
2277
|
+
|
|
2278
|
+
for (l = 1 << (8 - code_size); l > 0; l--)
|
|
2279
|
+
{
|
|
2280
|
+
JPGD_ASSERT(i < 256);
|
|
2281
|
+
|
|
2282
|
+
pH->look_up[code] = i;
|
|
2283
|
+
|
|
2284
|
+
bool has_extrabits = false;
|
|
2285
|
+
int extra_bits = 0;
|
|
2286
|
+
int num_extra_bits = i & 15;
|
|
2287
|
+
|
|
2288
|
+
int bits_to_fetch = code_size;
|
|
2289
|
+
if (num_extra_bits)
|
|
2290
|
+
{
|
|
2291
|
+
int total_codesize = code_size + num_extra_bits;
|
|
2292
|
+
if (total_codesize <= 8)
|
|
2293
|
+
{
|
|
2294
|
+
has_extrabits = true;
|
|
2295
|
+
extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));
|
|
2296
|
+
JPGD_ASSERT(extra_bits <= 0x7FFF);
|
|
2297
|
+
bits_to_fetch += num_extra_bits;
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
if (!has_extrabits)
|
|
2302
|
+
pH->look_up2[code] = i | (bits_to_fetch << 8);
|
|
2303
|
+
else
|
|
2304
|
+
pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);
|
|
2305
|
+
|
|
2306
|
+
code++;
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
else
|
|
2310
|
+
{
|
|
2311
|
+
subtree = (code >> (code_size - 8)) & 0xFF;
|
|
2312
|
+
|
|
2313
|
+
currententry = pH->look_up[subtree];
|
|
2314
|
+
|
|
2315
|
+
if (currententry == 0)
|
|
2316
|
+
{
|
|
2317
|
+
pH->look_up[subtree] = currententry = nextfreeentry;
|
|
2318
|
+
pH->look_up2[subtree] = currententry = nextfreeentry;
|
|
2319
|
+
|
|
2320
|
+
nextfreeentry -= 2;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
code <<= (16 - (code_size - 8));
|
|
2324
|
+
|
|
2325
|
+
for (l = code_size; l > 9; l--)
|
|
2326
|
+
{
|
|
2327
|
+
if ((code & 0x8000) == 0)
|
|
2328
|
+
currententry--;
|
|
2329
|
+
|
|
2330
|
+
if (pH->tree[-currententry - 1] == 0)
|
|
2331
|
+
{
|
|
2332
|
+
pH->tree[-currententry - 1] = nextfreeentry;
|
|
2333
|
+
|
|
2334
|
+
currententry = nextfreeentry;
|
|
2335
|
+
|
|
2336
|
+
nextfreeentry -= 2;
|
|
2337
|
+
}
|
|
2338
|
+
else
|
|
2339
|
+
currententry = pH->tree[-currententry - 1];
|
|
2340
|
+
|
|
2341
|
+
code <<= 1;
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
if ((code & 0x8000) == 0)
|
|
2345
|
+
currententry--;
|
|
2346
|
+
|
|
2347
|
+
pH->tree[-currententry - 1] = i;
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
p++;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
|
|
2354
|
+
// Verifies the quantization tables needed for this scan are available.
|
|
2355
|
+
void jpeg_decoder::check_quant_tables()
|
|
2356
|
+
{
|
|
2357
|
+
for (int i = 0; i < m_comps_in_scan; i++)
|
|
2358
|
+
if (m_quant[m_comp_quant[m_comp_list[i]]] == NULL)
|
|
2359
|
+
stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// Verifies that all the Huffman tables needed for this scan are available.
|
|
2363
|
+
void jpeg_decoder::check_huff_tables()
|
|
2364
|
+
{
|
|
2365
|
+
for (int i = 0; i < m_comps_in_scan; i++)
|
|
2366
|
+
{
|
|
2367
|
+
if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == NULL))
|
|
2368
|
+
stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
|
|
2369
|
+
|
|
2370
|
+
if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == NULL))
|
|
2371
|
+
stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)
|
|
2375
|
+
if (m_huff_num[i])
|
|
2376
|
+
{
|
|
2377
|
+
if (!m_pHuff_tabs[i])
|
|
2378
|
+
m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables));
|
|
2379
|
+
|
|
2380
|
+
make_huff_table(i, m_pHuff_tabs[i]);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
// Determines the component order inside each MCU.
|
|
2385
|
+
// Also calcs how many MCU's are on each row, etc.
|
|
2386
|
+
void jpeg_decoder::calc_mcu_block_order()
|
|
2387
|
+
{
|
|
2388
|
+
int component_num, component_id;
|
|
2389
|
+
int max_h_samp = 0, max_v_samp = 0;
|
|
2390
|
+
|
|
2391
|
+
for (component_id = 0; component_id < m_comps_in_frame; component_id++)
|
|
2392
|
+
{
|
|
2393
|
+
if (m_comp_h_samp[component_id] > max_h_samp)
|
|
2394
|
+
max_h_samp = m_comp_h_samp[component_id];
|
|
2395
|
+
|
|
2396
|
+
if (m_comp_v_samp[component_id] > max_v_samp)
|
|
2397
|
+
max_v_samp = m_comp_v_samp[component_id];
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
for (component_id = 0; component_id < m_comps_in_frame; component_id++)
|
|
2401
|
+
{
|
|
2402
|
+
m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;
|
|
2403
|
+
m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2406
|
+
if (m_comps_in_scan == 1)
|
|
2407
|
+
{
|
|
2408
|
+
m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];
|
|
2409
|
+
m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];
|
|
2410
|
+
}
|
|
2411
|
+
else
|
|
2412
|
+
{
|
|
2413
|
+
m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;
|
|
2414
|
+
m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
if (m_comps_in_scan == 1)
|
|
2418
|
+
{
|
|
2419
|
+
m_mcu_org[0] = m_comp_list[0];
|
|
2420
|
+
|
|
2421
|
+
m_blocks_per_mcu = 1;
|
|
2422
|
+
}
|
|
2423
|
+
else
|
|
2424
|
+
{
|
|
2425
|
+
m_blocks_per_mcu = 0;
|
|
2426
|
+
|
|
2427
|
+
for (component_num = 0; component_num < m_comps_in_scan; component_num++)
|
|
2428
|
+
{
|
|
2429
|
+
int num_blocks;
|
|
2430
|
+
|
|
2431
|
+
component_id = m_comp_list[component_num];
|
|
2432
|
+
|
|
2433
|
+
num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];
|
|
2434
|
+
|
|
2435
|
+
while (num_blocks--)
|
|
2436
|
+
m_mcu_org[m_blocks_per_mcu++] = component_id;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
// Starts a new scan.
|
|
2442
|
+
int jpeg_decoder::init_scan()
|
|
2443
|
+
{
|
|
2444
|
+
if (!locate_sos_marker())
|
|
2445
|
+
return JPGD_FALSE;
|
|
2446
|
+
|
|
2447
|
+
calc_mcu_block_order();
|
|
2448
|
+
|
|
2449
|
+
check_huff_tables();
|
|
2450
|
+
|
|
2451
|
+
check_quant_tables();
|
|
2452
|
+
|
|
2453
|
+
memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
|
|
2454
|
+
|
|
2455
|
+
m_eob_run = 0;
|
|
2456
|
+
|
|
2457
|
+
if (m_restart_interval)
|
|
2458
|
+
{
|
|
2459
|
+
m_restarts_left = m_restart_interval;
|
|
2460
|
+
m_next_restart_num = 0;
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
fix_in_buffer();
|
|
2464
|
+
|
|
2465
|
+
return JPGD_TRUE;
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
// Starts a frame. Determines if the number of components or sampling factors
|
|
2469
|
+
// are supported.
|
|
2470
|
+
void jpeg_decoder::init_frame()
|
|
2471
|
+
{
|
|
2472
|
+
int i;
|
|
2473
|
+
|
|
2474
|
+
if (m_comps_in_frame == 1)
|
|
2475
|
+
{
|
|
2476
|
+
if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))
|
|
2477
|
+
stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
|
|
2478
|
+
|
|
2479
|
+
m_scan_type = JPGD_GRAYSCALE;
|
|
2480
|
+
m_max_blocks_per_mcu = 1;
|
|
2481
|
+
m_max_mcu_x_size = 8;
|
|
2482
|
+
m_max_mcu_y_size = 8;
|
|
2483
|
+
}
|
|
2484
|
+
else if (m_comps_in_frame == 3)
|
|
2485
|
+
{
|
|
2486
|
+
if ( ((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||
|
|
2487
|
+
((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)) )
|
|
2488
|
+
stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
|
|
2489
|
+
|
|
2490
|
+
if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))
|
|
2491
|
+
{
|
|
2492
|
+
m_scan_type = JPGD_YH1V1;
|
|
2493
|
+
|
|
2494
|
+
m_max_blocks_per_mcu = 3;
|
|
2495
|
+
m_max_mcu_x_size = 8;
|
|
2496
|
+
m_max_mcu_y_size = 8;
|
|
2497
|
+
}
|
|
2498
|
+
else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))
|
|
2499
|
+
{
|
|
2500
|
+
m_scan_type = JPGD_YH2V1;
|
|
2501
|
+
m_max_blocks_per_mcu = 4;
|
|
2502
|
+
m_max_mcu_x_size = 16;
|
|
2503
|
+
m_max_mcu_y_size = 8;
|
|
2504
|
+
}
|
|
2505
|
+
else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))
|
|
2506
|
+
{
|
|
2507
|
+
m_scan_type = JPGD_YH1V2;
|
|
2508
|
+
m_max_blocks_per_mcu = 4;
|
|
2509
|
+
m_max_mcu_x_size = 8;
|
|
2510
|
+
m_max_mcu_y_size = 16;
|
|
2511
|
+
}
|
|
2512
|
+
else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))
|
|
2513
|
+
{
|
|
2514
|
+
m_scan_type = JPGD_YH2V2;
|
|
2515
|
+
m_max_blocks_per_mcu = 6;
|
|
2516
|
+
m_max_mcu_x_size = 16;
|
|
2517
|
+
m_max_mcu_y_size = 16;
|
|
2518
|
+
}
|
|
2519
|
+
else
|
|
2520
|
+
stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
|
|
2521
|
+
}
|
|
2522
|
+
else
|
|
2523
|
+
stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
|
|
2524
|
+
|
|
2525
|
+
m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;
|
|
2526
|
+
m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;
|
|
2527
|
+
|
|
2528
|
+
// These values are for the *destination* pixels: after conversion.
|
|
2529
|
+
if (m_scan_type == JPGD_GRAYSCALE)
|
|
2530
|
+
m_dest_bytes_per_pixel = 1;
|
|
2531
|
+
else
|
|
2532
|
+
m_dest_bytes_per_pixel = 4;
|
|
2533
|
+
|
|
2534
|
+
m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;
|
|
2535
|
+
|
|
2536
|
+
m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);
|
|
2537
|
+
|
|
2538
|
+
// Initialize two scan line buffers.
|
|
2539
|
+
m_pScan_line_0 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true);
|
|
2540
|
+
if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))
|
|
2541
|
+
m_pScan_line_1 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true);
|
|
2542
|
+
|
|
2543
|
+
m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;
|
|
2544
|
+
|
|
2545
|
+
// Should never happen
|
|
2546
|
+
if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)
|
|
2547
|
+
stop_decoding(JPGD_ASSERTION_ERROR);
|
|
2548
|
+
|
|
2549
|
+
// Allocate the coefficient buffer, enough for one MCU
|
|
2550
|
+
m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t));
|
|
2551
|
+
|
|
2552
|
+
for (i = 0; i < m_max_blocks_per_mcu; i++)
|
|
2553
|
+
m_mcu_block_max_zag[i] = 64;
|
|
2554
|
+
|
|
2555
|
+
m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0];
|
|
2556
|
+
m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame;
|
|
2557
|
+
m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu;
|
|
2558
|
+
// Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen).
|
|
2559
|
+
m_freq_domain_chroma_upsample = false;
|
|
2560
|
+
#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING
|
|
2561
|
+
m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3);
|
|
2562
|
+
#endif
|
|
2563
|
+
|
|
2564
|
+
if (m_freq_domain_chroma_upsample)
|
|
2565
|
+
m_pSample_buf = (uint8 *)alloc(m_expanded_blocks_per_row * 64);
|
|
2566
|
+
else
|
|
2567
|
+
m_pSample_buf = (uint8 *)alloc(m_max_blocks_per_row * 64);
|
|
2568
|
+
|
|
2569
|
+
m_total_lines_left = m_image_y_size;
|
|
2570
|
+
|
|
2571
|
+
m_mcu_lines_left = 0;
|
|
2572
|
+
|
|
2573
|
+
create_look_ups();
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
// The coeff_buf series of methods originally stored the coefficients
|
|
2577
|
+
// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache
|
|
2578
|
+
// was used to make this process more efficient. Now, we can store the entire
|
|
2579
|
+
// thing in RAM.
|
|
2580
|
+
jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)
|
|
2581
|
+
{
|
|
2582
|
+
coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));
|
|
2583
|
+
|
|
2584
|
+
cb->block_num_x = block_num_x;
|
|
2585
|
+
cb->block_num_y = block_num_y;
|
|
2586
|
+
cb->block_len_x = block_len_x;
|
|
2587
|
+
cb->block_len_y = block_len_y;
|
|
2588
|
+
cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t);
|
|
2589
|
+
cb->pData = (uint8 *)alloc(cb->block_size * block_num_x * block_num_y, true);
|
|
2590
|
+
return cb;
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y)
|
|
2594
|
+
{
|
|
2595
|
+
JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y));
|
|
2596
|
+
return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
// The following methods decode the various types of m_blocks encountered
|
|
2600
|
+
// in progressively encoded images.
|
|
2601
|
+
void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y)
|
|
2602
|
+
{
|
|
2603
|
+
int s, r;
|
|
2604
|
+
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
|
|
2605
|
+
|
|
2606
|
+
if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)
|
|
2607
|
+
{
|
|
2608
|
+
r = pD->get_bits_no_markers(s);
|
|
2609
|
+
s = JPGD_HUFF_EXTEND(r, s);
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);
|
|
2613
|
+
|
|
2614
|
+
p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y)
|
|
2618
|
+
{
|
|
2619
|
+
if (pD->get_bits_no_markers(1))
|
|
2620
|
+
{
|
|
2621
|
+
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
|
|
2622
|
+
|
|
2623
|
+
p[0] |= (1 << pD->m_successive_low);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y)
|
|
2628
|
+
{
|
|
2629
|
+
int k, s, r;
|
|
2630
|
+
|
|
2631
|
+
if (pD->m_eob_run)
|
|
2632
|
+
{
|
|
2633
|
+
pD->m_eob_run--;
|
|
2634
|
+
return;
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
|
|
2638
|
+
|
|
2639
|
+
for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
|
|
2640
|
+
{
|
|
2641
|
+
s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
|
|
2642
|
+
|
|
2643
|
+
r = s >> 4;
|
|
2644
|
+
s &= 15;
|
|
2645
|
+
|
|
2646
|
+
if (s)
|
|
2647
|
+
{
|
|
2648
|
+
if ((k += r) > 63)
|
|
2649
|
+
pD->stop_decoding(JPGD_DECODE_ERROR);
|
|
2650
|
+
|
|
2651
|
+
r = pD->get_bits_no_markers(s);
|
|
2652
|
+
s = JPGD_HUFF_EXTEND(r, s);
|
|
2653
|
+
|
|
2654
|
+
p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
|
|
2655
|
+
}
|
|
2656
|
+
else
|
|
2657
|
+
{
|
|
2658
|
+
if (r == 15)
|
|
2659
|
+
{
|
|
2660
|
+
if ((k += 15) > 63)
|
|
2661
|
+
pD->stop_decoding(JPGD_DECODE_ERROR);
|
|
2662
|
+
}
|
|
2663
|
+
else
|
|
2664
|
+
{
|
|
2665
|
+
pD->m_eob_run = 1 << r;
|
|
2666
|
+
|
|
2667
|
+
if (r)
|
|
2668
|
+
pD->m_eob_run += pD->get_bits_no_markers(r);
|
|
2669
|
+
|
|
2670
|
+
pD->m_eob_run--;
|
|
2671
|
+
|
|
2672
|
+
break;
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y)
|
|
2679
|
+
{
|
|
2680
|
+
int s, k, r;
|
|
2681
|
+
int p1 = 1 << pD->m_successive_low;
|
|
2682
|
+
int m1 = (-1) << pD->m_successive_low;
|
|
2683
|
+
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
|
|
2684
|
+
|
|
2685
|
+
JPGD_ASSERT(pD->m_spectral_end <= 63);
|
|
2686
|
+
|
|
2687
|
+
k = pD->m_spectral_start;
|
|
2688
|
+
|
|
2689
|
+
if (pD->m_eob_run == 0)
|
|
2690
|
+
{
|
|
2691
|
+
for ( ; k <= pD->m_spectral_end; k++)
|
|
2692
|
+
{
|
|
2693
|
+
s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
|
|
2694
|
+
|
|
2695
|
+
r = s >> 4;
|
|
2696
|
+
s &= 15;
|
|
2697
|
+
|
|
2698
|
+
if (s)
|
|
2699
|
+
{
|
|
2700
|
+
if (s != 1)
|
|
2701
|
+
pD->stop_decoding(JPGD_DECODE_ERROR);
|
|
2702
|
+
|
|
2703
|
+
if (pD->get_bits_no_markers(1))
|
|
2704
|
+
s = p1;
|
|
2705
|
+
else
|
|
2706
|
+
s = m1;
|
|
2707
|
+
}
|
|
2708
|
+
else
|
|
2709
|
+
{
|
|
2710
|
+
if (r != 15)
|
|
2711
|
+
{
|
|
2712
|
+
pD->m_eob_run = 1 << r;
|
|
2713
|
+
|
|
2714
|
+
if (r)
|
|
2715
|
+
pD->m_eob_run += pD->get_bits_no_markers(r);
|
|
2716
|
+
|
|
2717
|
+
break;
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
do
|
|
2722
|
+
{
|
|
2723
|
+
jpgd_block_t *this_coef = p + g_ZAG[k & 63];
|
|
2724
|
+
|
|
2725
|
+
if (*this_coef != 0)
|
|
2726
|
+
{
|
|
2727
|
+
if (pD->get_bits_no_markers(1))
|
|
2728
|
+
{
|
|
2729
|
+
if ((*this_coef & p1) == 0)
|
|
2730
|
+
{
|
|
2731
|
+
if (*this_coef >= 0)
|
|
2732
|
+
*this_coef = static_cast<jpgd_block_t>(*this_coef + p1);
|
|
2733
|
+
else
|
|
2734
|
+
*this_coef = static_cast<jpgd_block_t>(*this_coef + m1);
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
else
|
|
2739
|
+
{
|
|
2740
|
+
if (--r < 0)
|
|
2741
|
+
break;
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
k++;
|
|
2745
|
+
|
|
2746
|
+
} while (k <= pD->m_spectral_end);
|
|
2747
|
+
|
|
2748
|
+
if ((s) && (k < 64))
|
|
2749
|
+
{
|
|
2750
|
+
p[g_ZAG[k]] = static_cast<jpgd_block_t>(s);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
if (pD->m_eob_run > 0)
|
|
2756
|
+
{
|
|
2757
|
+
for ( ; k <= pD->m_spectral_end; k++)
|
|
2758
|
+
{
|
|
2759
|
+
jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis
|
|
2760
|
+
|
|
2761
|
+
if (*this_coef != 0)
|
|
2762
|
+
{
|
|
2763
|
+
if (pD->get_bits_no_markers(1))
|
|
2764
|
+
{
|
|
2765
|
+
if ((*this_coef & p1) == 0)
|
|
2766
|
+
{
|
|
2767
|
+
if (*this_coef >= 0)
|
|
2768
|
+
*this_coef = static_cast<jpgd_block_t>(*this_coef + p1);
|
|
2769
|
+
else
|
|
2770
|
+
*this_coef = static_cast<jpgd_block_t>(*this_coef + m1);
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
pD->m_eob_run--;
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
// Decode a scan in a progressively encoded image.
|
|
2781
|
+
void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)
|
|
2782
|
+
{
|
|
2783
|
+
int mcu_row, mcu_col, mcu_block;
|
|
2784
|
+
int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS];
|
|
2785
|
+
|
|
2786
|
+
memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
|
|
2787
|
+
|
|
2788
|
+
for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)
|
|
2789
|
+
{
|
|
2790
|
+
int component_num, component_id;
|
|
2791
|
+
|
|
2792
|
+
memset(block_x_mcu, 0, sizeof(block_x_mcu));
|
|
2793
|
+
|
|
2794
|
+
for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
|
|
2795
|
+
{
|
|
2796
|
+
int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
|
|
2797
|
+
|
|
2798
|
+
if ((m_restart_interval) && (m_restarts_left == 0))
|
|
2799
|
+
process_restart();
|
|
2800
|
+
|
|
2801
|
+
for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
|
|
2802
|
+
{
|
|
2803
|
+
component_id = m_mcu_org[mcu_block];
|
|
2804
|
+
|
|
2805
|
+
decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
|
|
2806
|
+
|
|
2807
|
+
if (m_comps_in_scan == 1)
|
|
2808
|
+
block_x_mcu[component_id]++;
|
|
2809
|
+
else
|
|
2810
|
+
{
|
|
2811
|
+
if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
|
|
2812
|
+
{
|
|
2813
|
+
block_x_mcu_ofs = 0;
|
|
2814
|
+
|
|
2815
|
+
if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
|
|
2816
|
+
{
|
|
2817
|
+
block_y_mcu_ofs = 0;
|
|
2818
|
+
block_x_mcu[component_id] += m_comp_h_samp[component_id];
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
m_restarts_left--;
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2827
|
+
if (m_comps_in_scan == 1)
|
|
2828
|
+
m_block_y_mcu[m_comp_list[0]]++;
|
|
2829
|
+
else
|
|
2830
|
+
{
|
|
2831
|
+
for (component_num = 0; component_num < m_comps_in_scan; component_num++)
|
|
2832
|
+
{
|
|
2833
|
+
component_id = m_comp_list[component_num];
|
|
2834
|
+
m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
// Decode a progressively encoded image.
|
|
2841
|
+
void jpeg_decoder::init_progressive()
|
|
2842
|
+
{
|
|
2843
|
+
int i;
|
|
2844
|
+
|
|
2845
|
+
if (m_comps_in_frame == 4)
|
|
2846
|
+
stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
|
|
2847
|
+
|
|
2848
|
+
// Allocate the coefficient buffers.
|
|
2849
|
+
for (i = 0; i < m_comps_in_frame; i++)
|
|
2850
|
+
{
|
|
2851
|
+
m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1);
|
|
2852
|
+
m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8);
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
for ( ; ; )
|
|
2856
|
+
{
|
|
2857
|
+
int dc_only_scan, refinement_scan;
|
|
2858
|
+
pDecode_block_func decode_block_func;
|
|
2859
|
+
|
|
2860
|
+
if (!init_scan())
|
|
2861
|
+
break;
|
|
2862
|
+
|
|
2863
|
+
dc_only_scan = (m_spectral_start == 0);
|
|
2864
|
+
refinement_scan = (m_successive_high != 0);
|
|
2865
|
+
|
|
2866
|
+
if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))
|
|
2867
|
+
stop_decoding(JPGD_BAD_SOS_SPECTRAL);
|
|
2868
|
+
|
|
2869
|
+
if (dc_only_scan)
|
|
2870
|
+
{
|
|
2871
|
+
if (m_spectral_end)
|
|
2872
|
+
stop_decoding(JPGD_BAD_SOS_SPECTRAL);
|
|
2873
|
+
}
|
|
2874
|
+
else if (m_comps_in_scan != 1) /* AC scans can only contain one component */
|
|
2875
|
+
stop_decoding(JPGD_BAD_SOS_SPECTRAL);
|
|
2876
|
+
|
|
2877
|
+
if ((refinement_scan) && (m_successive_low != m_successive_high - 1))
|
|
2878
|
+
stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);
|
|
2879
|
+
|
|
2880
|
+
if (dc_only_scan)
|
|
2881
|
+
{
|
|
2882
|
+
if (refinement_scan)
|
|
2883
|
+
decode_block_func = decode_block_dc_refine;
|
|
2884
|
+
else
|
|
2885
|
+
decode_block_func = decode_block_dc_first;
|
|
2886
|
+
}
|
|
2887
|
+
else
|
|
2888
|
+
{
|
|
2889
|
+
if (refinement_scan)
|
|
2890
|
+
decode_block_func = decode_block_ac_refine;
|
|
2891
|
+
else
|
|
2892
|
+
decode_block_func = decode_block_ac_first;
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
decode_scan(decode_block_func);
|
|
2896
|
+
|
|
2897
|
+
m_bits_left = 16;
|
|
2898
|
+
get_bits(16);
|
|
2899
|
+
get_bits(16);
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
m_comps_in_scan = m_comps_in_frame;
|
|
2903
|
+
|
|
2904
|
+
for (i = 0; i < m_comps_in_frame; i++)
|
|
2905
|
+
m_comp_list[i] = i;
|
|
2906
|
+
|
|
2907
|
+
calc_mcu_block_order();
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
void jpeg_decoder::init_sequential()
|
|
2911
|
+
{
|
|
2912
|
+
if (!init_scan())
|
|
2913
|
+
stop_decoding(JPGD_UNEXPECTED_MARKER);
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2916
|
+
void jpeg_decoder::decode_start()
|
|
2917
|
+
{
|
|
2918
|
+
init_frame();
|
|
2919
|
+
|
|
2920
|
+
if (m_progressive_flag)
|
|
2921
|
+
init_progressive();
|
|
2922
|
+
else
|
|
2923
|
+
init_sequential();
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream)
|
|
2927
|
+
{
|
|
2928
|
+
init(pStream);
|
|
2929
|
+
locate_sof_marker();
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream)
|
|
2933
|
+
{
|
|
2934
|
+
if (setjmp(m_jmp_state))
|
|
2935
|
+
return;
|
|
2936
|
+
decode_init(pStream);
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
int jpeg_decoder::begin_decoding()
|
|
2940
|
+
{
|
|
2941
|
+
if (m_ready_flag)
|
|
2942
|
+
return JPGD_SUCCESS;
|
|
2943
|
+
|
|
2944
|
+
if (m_error_code)
|
|
2945
|
+
return JPGD_FAILED;
|
|
2946
|
+
|
|
2947
|
+
if (setjmp(m_jmp_state))
|
|
2948
|
+
return JPGD_FAILED;
|
|
2949
|
+
|
|
2950
|
+
decode_start();
|
|
2951
|
+
|
|
2952
|
+
m_ready_flag = true;
|
|
2953
|
+
|
|
2954
|
+
return JPGD_SUCCESS;
|
|
2955
|
+
}
|
|
2956
|
+
|
|
2957
|
+
jpeg_decoder::~jpeg_decoder()
|
|
2958
|
+
{
|
|
2959
|
+
free_all_blocks();
|
|
2960
|
+
}
|
|
2961
|
+
|
|
2962
|
+
jpeg_decoder_file_stream::jpeg_decoder_file_stream()
|
|
2963
|
+
{
|
|
2964
|
+
m_pFile = NULL;
|
|
2965
|
+
m_eof_flag = false;
|
|
2966
|
+
m_error_flag = false;
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
void jpeg_decoder_file_stream::close()
|
|
2970
|
+
{
|
|
2971
|
+
if (m_pFile)
|
|
2972
|
+
{
|
|
2973
|
+
fclose(m_pFile);
|
|
2974
|
+
m_pFile = NULL;
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
m_eof_flag = false;
|
|
2978
|
+
m_error_flag = false;
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
jpeg_decoder_file_stream::~jpeg_decoder_file_stream()
|
|
2982
|
+
{
|
|
2983
|
+
close();
|
|
2984
|
+
}
|
|
2985
|
+
|
|
2986
|
+
bool jpeg_decoder_file_stream::open(const char *Pfilename)
|
|
2987
|
+
{
|
|
2988
|
+
close();
|
|
2989
|
+
|
|
2990
|
+
m_eof_flag = false;
|
|
2991
|
+
m_error_flag = false;
|
|
2992
|
+
|
|
2993
|
+
#if defined(_MSC_VER)
|
|
2994
|
+
m_pFile = NULL;
|
|
2995
|
+
fopen_s(&m_pFile, Pfilename, "rb");
|
|
2996
|
+
#else
|
|
2997
|
+
m_pFile = fopen(Pfilename, "rb");
|
|
2998
|
+
#endif
|
|
2999
|
+
return m_pFile != NULL;
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
int jpeg_decoder_file_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag)
|
|
3003
|
+
{
|
|
3004
|
+
if (!m_pFile)
|
|
3005
|
+
return -1;
|
|
3006
|
+
|
|
3007
|
+
if (m_eof_flag)
|
|
3008
|
+
{
|
|
3009
|
+
*pEOF_flag = true;
|
|
3010
|
+
return 0;
|
|
3011
|
+
}
|
|
3012
|
+
|
|
3013
|
+
if (m_error_flag)
|
|
3014
|
+
return -1;
|
|
3015
|
+
|
|
3016
|
+
int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));
|
|
3017
|
+
if (bytes_read < max_bytes_to_read)
|
|
3018
|
+
{
|
|
3019
|
+
if (ferror(m_pFile))
|
|
3020
|
+
{
|
|
3021
|
+
m_error_flag = true;
|
|
3022
|
+
return -1;
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
m_eof_flag = true;
|
|
3026
|
+
*pEOF_flag = true;
|
|
3027
|
+
}
|
|
3028
|
+
|
|
3029
|
+
return bytes_read;
|
|
3030
|
+
}
|
|
3031
|
+
|
|
3032
|
+
bool jpeg_decoder_mem_stream::open(const uint8 *pSrc_data, uint size)
|
|
3033
|
+
{
|
|
3034
|
+
close();
|
|
3035
|
+
m_pSrc_data = pSrc_data;
|
|
3036
|
+
m_ofs = 0;
|
|
3037
|
+
m_size = size;
|
|
3038
|
+
return true;
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
int jpeg_decoder_mem_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag)
|
|
3042
|
+
{
|
|
3043
|
+
*pEOF_flag = false;
|
|
3044
|
+
|
|
3045
|
+
if (!m_pSrc_data)
|
|
3046
|
+
return -1;
|
|
3047
|
+
|
|
3048
|
+
uint bytes_remaining = m_size - m_ofs;
|
|
3049
|
+
if ((uint)max_bytes_to_read > bytes_remaining)
|
|
3050
|
+
{
|
|
3051
|
+
max_bytes_to_read = bytes_remaining;
|
|
3052
|
+
*pEOF_flag = true;
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);
|
|
3056
|
+
m_ofs += max_bytes_to_read;
|
|
3057
|
+
|
|
3058
|
+
return max_bytes_to_read;
|
|
3059
|
+
}
|
|
3060
|
+
|
|
3061
|
+
unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps)
|
|
3062
|
+
{
|
|
3063
|
+
if (!actual_comps)
|
|
3064
|
+
return NULL;
|
|
3065
|
+
*actual_comps = 0;
|
|
3066
|
+
|
|
3067
|
+
if ((!pStream) || (!width) || (!height) || (!req_comps))
|
|
3068
|
+
return NULL;
|
|
3069
|
+
|
|
3070
|
+
if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))
|
|
3071
|
+
return NULL;
|
|
3072
|
+
|
|
3073
|
+
jpeg_decoder decoder(pStream);
|
|
3074
|
+
if (decoder.get_error_code() != JPGD_SUCCESS)
|
|
3075
|
+
return NULL;
|
|
3076
|
+
|
|
3077
|
+
const int image_width = decoder.get_width(), image_height = decoder.get_height();
|
|
3078
|
+
*width = image_width;
|
|
3079
|
+
*height = image_height;
|
|
3080
|
+
*actual_comps = decoder.get_num_components();
|
|
3081
|
+
|
|
3082
|
+
if (decoder.begin_decoding() != JPGD_SUCCESS)
|
|
3083
|
+
return NULL;
|
|
3084
|
+
|
|
3085
|
+
const int dst_bpl = image_width * req_comps;
|
|
3086
|
+
|
|
3087
|
+
uint8 *pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);
|
|
3088
|
+
if (!pImage_data)
|
|
3089
|
+
return NULL;
|
|
3090
|
+
|
|
3091
|
+
for (int y = 0; y < image_height; y++)
|
|
3092
|
+
{
|
|
3093
|
+
const uint8* pScan_line;
|
|
3094
|
+
uint scan_line_len;
|
|
3095
|
+
if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)
|
|
3096
|
+
{
|
|
3097
|
+
jpgd_free(pImage_data);
|
|
3098
|
+
return NULL;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
uint8 *pDst = pImage_data + y * dst_bpl;
|
|
3102
|
+
|
|
3103
|
+
if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))
|
|
3104
|
+
memcpy(pDst, pScan_line, dst_bpl);
|
|
3105
|
+
else if (decoder.get_num_components() == 1)
|
|
3106
|
+
{
|
|
3107
|
+
if (req_comps == 3)
|
|
3108
|
+
{
|
|
3109
|
+
for (int x = 0; x < image_width; x++)
|
|
3110
|
+
{
|
|
3111
|
+
uint8 luma = pScan_line[x];
|
|
3112
|
+
pDst[0] = luma;
|
|
3113
|
+
pDst[1] = luma;
|
|
3114
|
+
pDst[2] = luma;
|
|
3115
|
+
pDst += 3;
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
else
|
|
3119
|
+
{
|
|
3120
|
+
for (int x = 0; x < image_width; x++)
|
|
3121
|
+
{
|
|
3122
|
+
uint8 luma = pScan_line[x];
|
|
3123
|
+
pDst[0] = luma;
|
|
3124
|
+
pDst[1] = luma;
|
|
3125
|
+
pDst[2] = luma;
|
|
3126
|
+
pDst[3] = 255;
|
|
3127
|
+
pDst += 4;
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
else if (decoder.get_num_components() == 3)
|
|
3132
|
+
{
|
|
3133
|
+
if (req_comps == 1)
|
|
3134
|
+
{
|
|
3135
|
+
const int YR = 19595, YG = 38470, YB = 7471;
|
|
3136
|
+
for (int x = 0; x < image_width; x++)
|
|
3137
|
+
{
|
|
3138
|
+
int r = pScan_line[x*4+0];
|
|
3139
|
+
int g = pScan_line[x*4+1];
|
|
3140
|
+
int b = pScan_line[x*4+2];
|
|
3141
|
+
*pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
else
|
|
3145
|
+
{
|
|
3146
|
+
for (int x = 0; x < image_width; x++)
|
|
3147
|
+
{
|
|
3148
|
+
pDst[0] = pScan_line[x*4+0];
|
|
3149
|
+
pDst[1] = pScan_line[x*4+1];
|
|
3150
|
+
pDst[2] = pScan_line[x*4+2];
|
|
3151
|
+
pDst += 3;
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3157
|
+
return pImage_data;
|
|
3158
|
+
}
|
|
3159
|
+
|
|
3160
|
+
unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps)
|
|
3161
|
+
{
|
|
3162
|
+
jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);
|
|
3163
|
+
return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps);
|
|
3164
|
+
}
|
|
3165
|
+
|
|
3166
|
+
unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps)
|
|
3167
|
+
{
|
|
3168
|
+
jpgd::jpeg_decoder_file_stream file_stream;
|
|
3169
|
+
if (!file_stream.open(pSrc_filename))
|
|
3170
|
+
return NULL;
|
|
3171
|
+
return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps);
|
|
3172
|
+
}
|
|
3173
|
+
|
|
3174
|
+
} // namespace jpgd
|