diff --git a/codestream/aclosslessscan.cpp b/codestream/aclosslessscan.cpp index cbfd282..e461838 100644 --- a/codestream/aclosslessscan.cpp +++ b/codestream/aclosslessscan.cpp @@ -467,7 +467,6 @@ bool ACLosslessScan::ParseMCU(void) // Loop over lines and columns do { - bool startofline = true; do { if (BeginReadMCU(m_Coder.ByteStreamOf())) { ParseMCU(prev,top); @@ -475,15 +474,14 @@ bool ACLosslessScan::ParseMCU(void) // Only if this is not due to a DNL marker that has been detected. if (m_ulPixelHeight != 0 && !hasFoundDNL()) { ClearMCU(top); - } else if (!startofline) { + } else { // The problem is here that the DNL marker might have been detected, even though decoding // is not yet done completely. This may be because there are still just enough bits in the // AC coding engine present to run a single decode. Big Outch! Just continue decoding in // this case. ParseMCU(prev,top); - } else break; + } } - startofline = false; } while(AdvanceToTheRight()); // // Reset conditioning to the left diff --git a/codestream/acrefinementscan.hpp b/codestream/acrefinementscan.hpp index 6dff925..d88fdda 100644 --- a/codestream/acrefinementscan.hpp +++ b/codestream/acrefinementscan.hpp @@ -204,7 +204,11 @@ class ACRefinementScan : public EntropyParser { virtual bool ParseMCU(void); // // Write a single MCU in this scan. - virtual bool WriteMCU(void); + virtual bool WriteMCU(void); + // + // Post the height of the frame in lines. This happens + // when the DNL marker is processed. + virtual void PostImageHeight(ULONG) {} // // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. diff --git a/codestream/acsequentialscan.hpp b/codestream/acsequentialscan.hpp index fbe7941..389e9a2 100644 --- a/codestream/acsequentialscan.hpp +++ b/codestream/acsequentialscan.hpp @@ -355,6 +355,10 @@ class ACSequentialScan : public EntropyParser { // Write a single MCU in this scan. virtual bool WriteMCU(void); // + // Post the height of the frame in lines. This happens + // when the DNL marker is processed. + virtual void PostImageHeight(ULONG) {} + // // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. virtual void OptimizeBlock(LONG bx,LONG by,UBYTE component,double critical, diff --git a/codestream/entropyparser.cpp b/codestream/entropyparser.cpp index 5b3858c..d7b11ef 100644 --- a/codestream/entropyparser.cpp +++ b/codestream/entropyparser.cpp @@ -235,6 +235,7 @@ bool EntropyParser::ParseDNLMarker(class ByteStream *io) JPG_THROW(MALFORMED_STREAM,"EntropyParser::ParseDNLMarker", "frame height as indicated by the DNL marker is corrupt, must be > 0"); + PostImageHeight(dt); m_pFrame->PostImageHeight(dt); m_bDNLFound = true; diff --git a/codestream/entropyparser.hpp b/codestream/entropyparser.hpp index b583e98..dac7ef9 100644 --- a/codestream/entropyparser.hpp +++ b/codestream/entropyparser.hpp @@ -211,7 +211,11 @@ class EntropyParser : public JKeeper { virtual bool ParseMCU(void) = 0; // // Write a single MCU in this scan. - virtual bool WriteMCU(void) = 0; + virtual bool WriteMCU(void) = 0; + // + // Define the image size if it is not yet known here. This is + // called whenever the DNL marker is parsed in. + virtual void PostImageHeight(ULONG height) = 0; // // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. This runs an optimization for a single diff --git a/codestream/jpeglsscan.hpp b/codestream/jpeglsscan.hpp index 324a8f4..62d3b9f 100644 --- a/codestream/jpeglsscan.hpp +++ b/codestream/jpeglsscan.hpp @@ -695,7 +695,11 @@ class JPEGLSScan : public EntropyParser { virtual bool ParseMCU(void) = 0; // // Write a single MCU in this scan. - virtual bool WriteMCU(void) = 0; + virtual bool WriteMCU(void) = 0; + // + // Post the height of the frame in lines. This happens + // when the DNL marker is processed. + virtual void PostImageHeight(ULONG) {} // // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. diff --git a/codestream/losslessscan.cpp b/codestream/losslessscan.cpp index 6fd9c93..2b4e6dc 100644 --- a/codestream/losslessscan.cpp +++ b/codestream/losslessscan.cpp @@ -432,7 +432,6 @@ bool LosslessScan::ParseMCU(void) // Loop over lines and columns do { - bool startofline = true; do { if (BeginReadMCU(m_Stream.ByteStreamOf())) { ParseMCU(prev,top); @@ -440,14 +439,13 @@ bool LosslessScan::ParseMCU(void) // Only if this is not due to a DNL marker that has been detected. if (m_ulPixelHeight != 0 && !hasFoundDNL()) { ClearMCU(top); - } else if (!startofline) { + } else { // The problem is here that the DNL marker might have been detected, even though decoding // is not yet done completely. This may be because there are still just enough bits in the // bitream present to run a single decode. Big Outch! Just continue decoding in this case. ParseMCU(prev,top); - } else break; + } } - startofline = false; } while(AdvanceToTheRight()); // // Advance to the next line. diff --git a/codestream/predictivescan.cpp b/codestream/predictivescan.cpp index 1bbd86f..df03075 100644 --- a/codestream/predictivescan.cpp +++ b/codestream/predictivescan.cpp @@ -206,6 +206,15 @@ void PredictiveScan::RestartOnMarker(void) } /// +/// PredictiveScan::PostImageHeight +// Post the height of the frame in lines. This happens +// when the DNL marker is processed. +void PredictiveScan::PostImageHeight(ULONG height) +{ + m_ulPixelHeight = height; +} +/// + /// PredictiveScan::OptimizeBlock // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. diff --git a/codestream/predictivescan.hpp b/codestream/predictivescan.hpp index 639b089..9585056 100644 --- a/codestream/predictivescan.hpp +++ b/codestream/predictivescan.hpp @@ -196,6 +196,10 @@ class PredictiveScan : public EntropyParser { // of the restart interval. void RestartOnMarker(void); // + // Post the height of the frame in lines. This happens + // when the DNL marker is processed. + void PostImageHeight(ULONG height); + // // Start making an optimization run to adjust the coefficients. virtual void StartOptimizeScan(class BufferCtrl *ctrl); // diff --git a/codestream/refinementscan.hpp b/codestream/refinementscan.hpp index 5c29145..9155650 100644 --- a/codestream/refinementscan.hpp +++ b/codestream/refinementscan.hpp @@ -178,6 +178,10 @@ class RefinementScan : public EntropyParser { // Write a single MCU in this scan. virtual bool WriteMCU(void); // + // Post the height of the frame in lines. This happens + // when the DNL marker is processed. + virtual void PostImageHeight(ULONG) {} + // // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. virtual void OptimizeBlock(LONG bx,LONG by,UBYTE component,double critical, diff --git a/codestream/sequentialscan.hpp b/codestream/sequentialscan.hpp index adf6aa2..1dbfc48 100644 --- a/codestream/sequentialscan.hpp +++ b/codestream/sequentialscan.hpp @@ -206,6 +206,10 @@ class SequentialScan : public EntropyParser { // Write a single MCU in this scan. virtual bool WriteMCU(void); // + // Post the height of the frame in lines. This happens + // when the DNL marker is processed. + virtual void PostImageHeight(ULONG) {} + // // Make an R/D optimization for the given scan by potentially pushing // coefficients into other bins. This runs an optimization for a single // block and requires external control to run over the blocks.