zxing_cpp 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|