?? rawnjl2.cc
字號:
//cerr << "\tRUNcnt " << RUNcnt << endl; // Encode length of run (A.7.1.2) ... Uint16 rm; while (RUNcnt >= (rm=J_rm[RUNIndex])) {//cerr << "\tRUNIndex " << RUNIndex << endl;//cerr << "\trm " << rm << endl; writeBit(out,1); RUNcnt-=rm;//cerr << "\tRUNcnt decremented to " << RUNcnt << endl; Assert(RUNcnt >= 0); // is why int not unsigned if (RUNIndex < 31) { // ie. value ranges from 0..31 ++RUNIndex;//cerr << "\tRUNIndex incremented to " << RUNIndex << endl; } } if (col < COLUMNS) { // Must have been terminated by different value//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;//cerr << "\tcol " << col << endl;//cerr << "\tDifferent value is " << thisRow[col] << endl; writeBit(out,0); // Append least significant J[RUNIndex] bits Uint16 bits=J[RUNIndex]; Uint32 value=RUNcnt; Assert(value < J_rm[RUNIndex]); // Does it really fit in this ? It should else would have been coded by J_rm[RUNIndex]//cerr << "\tRemaining RUNcnt " << RUNcnt << endl;//cerr << "\tEncoding in bits " << bits << endl; // msb bit is written first while (bits--) { Uint32 bit=(value>>bits)&1; writeBit(out,bit); // use the decremented bits as shift } // Encode run interruption sample (A.7.2) ...//cerr << "\tcol at end of run " << col << endl; Assert(col<COLUMNS);//cerr << "\tBefore encoding value that ends run " << endl;//dumpWriteBitPosition();//cerr << "\tValue that ends run " << thisRow[col] << endl; // First update local context for interrupting sample, since weren't kept updated during run if (row > 0) { Rb=prevRow[col]; Ra=(col > 0) ? thisRow[col-1] : Rb; } else { Rb=0; Ra=(col > 0) ? thisRow[col-1] : 0; }//cerr << "\t\tUpdated Ra = " << Ra << endl;//cerr << "\t\tUpdated Rb = " << Rb << endl; codecRunEndSample(thisRow[col],Ra,Rb,RANGE,NEAR,MAXVAL,RESET,LIMIT,qbpp,J[RUNIndex],A,N,Nn,in,out,decompressing);//cerr << "\tAfter encoding value that ends run " << endl;//dumpWriteBitPosition(); if (RUNIndex > 0) { --RUNIndex; // NB. Do this AFTER J[RUNIndex] used in the limited length Golomb coding//cerr << "\tRUNIndex decremented to " << RUNIndex << endl; } } else { // Aborted at end of row//cerr << "\tEnd of row" << endl; if (RUNcnt > 0) { writeBit(out,1); // Append an extra 1 // decoder knows to stop at end of row // though remainder can't be > 1<<J[RUNIndex]//cerr << "1 for end of row" << endl;//cerr << "\tAfter indicating end of row " << endl;//dumpWriteBitPosition(); } } } } else { // Regular mode // Gradient quantization ... (A.3.3) Int16 Q1,Q2,Q3; if (D1 <= -T3) Q1=-4; else if (D1 <= -T2) Q1=-3; else if (D1 <= -T1) Q1=-2; else if (D1 < -NEAR) Q1=-1; else if (D1 <= NEAR) Q1= 0; else if (D1 < T1) Q1= 1; else if (D1 < T2) Q1= 2; else if (D1 < T3) Q1= 3; else Q1= 4; if (D2 <= -T3) Q2=-4; else if (D2 <= -T2) Q2=-3; else if (D2 <= -T1) Q2=-2; else if (D2 < -NEAR) Q2=-1; else if (D2 <= NEAR) Q2= 0; else if (D2 < T1) Q2= 1; else if (D2 < T2) Q2= 2; else if (D2 < T3) Q2= 3; else Q2= 4; if (D3 <= -T3) Q3=-4; else if (D3 <= -T2) Q3=-3; else if (D3 <= -T1) Q3=-2; else if (D3 < -NEAR) Q3=-1; else if (D3 <= NEAR) Q3= 0; else if (D3 < T1) Q3= 1; else if (D3 < T2) Q3= 2; else if (D3 < T3) Q3= 3; else Q3= 4;//cerr << "\t\tQ1 = " << Q1 << endl;//cerr << "\t\tQ2 = " << Q2 << endl;//cerr << "\t\tQ3 = " << Q3 << endl; // Context merging and determination of SIGN ... (A.3.4) Int16 SIGN; // "If the 1st non-zero component of vector (Q1,Q2,Q3) is negative" ... if ( Q1 < 0 || (Q1 == 0 && Q2 < 0) || (Q1 == 0 && Q2 == 0 && Q3 < 0) ) { Q1=-Q1; Q2=-Q2; Q3=-Q3; SIGN=-1; // signifies -ve } else { SIGN=1; // signifies +ve }//cerr << "\t\tSIGN= " << SIGN << endl;//cerr << "\t\tQ1 after SIGN = " << Q1 << endl;//cerr << "\t\tQ2 after SIGN = " << Q2 << endl;//cerr << "\t\tQ3 after SIGN = " << Q3 << endl; // The derivation of Q is not specified in the standard :( // Let's try this approach .... // Q1 can be 0 to 4 only // Q1 1 to 4 and Q2 -4 to 4 and Q3 -4 to 4 = 4*9*9 = 324 // Q1 0 and Q2 1 to 4 only and Q3 -4 to 4 = 1*4*9 = 36 // Q1 0 and Q2 0 and Q3 0 to 4 = 1*1*5 = 5 // total of 365 // and 0,0,0 (Q == 360) only occurs for run mode or regular mode with sample interleaved Uint16 Q; if (Q1 == 0) { if (Q2 == 0) { Q=360+Q3; // fills 360..364 } else { // Q2 is 1 to 4 Q=324+(Q2-1)*9+(Q3+4); // fills 324..359 } } else { // Q1 is 1 to 4 Q=(Q1-1)*81+(Q2+4)*9+(Q3+4); // fills 0..323 }//cerr << "\t\tQ = " << Q << endl;//if (Q >= nContexts) {// cerr << "\t\tQ1 after SIGN = " << Q1 << endl;// cerr << "\t\tQ2 after SIGN = " << Q2 << endl;// cerr << "\t\tQ3 after SIGN = " << Q3 << endl;// cerr << "\t\tQ itself = " << Q << endl;//} Assert(Q<nContexts); // Just in case // Figure A.5 Edge detecting predictor ... Int32 Px; // Predicted value - not Uint16 to allow overrange before clamping if (Rc >= Maximum(Ra,Rb)) Px = Minimum(Ra,Rb); else if (Rc <= Minimum(Ra,Rb)) Px = Maximum(Ra,Rb); else Px = (Int32)Ra+Rb-Rc;//cerr << "\t\tPx = " << Px << endl; // Figure A.6 Prediction correction and clamping ... Px = Px + ((SIGN > 0) ? C[Q] : -C[Q]);//cerr << "\t\tC[Q] = " << C[Q] << endl;//cerr << "\t\tPx corrected = " << Px << endl; clampPredictedValue(Px,MAXVAL);//cerr << "\t\tPx clamped = " << Px << endl; // Figure A.10 Prediction error Golomb encoding and decoding... Uint16 k = determineGolombParameter(N[Q],A[Q]); Uint32 MErrval; Int32 Errval; Int32 updateErrval; if (decompressing) { // Decode Golomb mapped error from input... decodeMappedErrvalWithGolomb(k,LIMIT,qbpp,MErrval,in);//cerr << "\t\tMErrval = " << MErrval << endl; // Unmap error from non-negative (inverse of A.5.2 Figure A.11) ... if (NEAR == 0 && k == 0 && 2*B[Q] <= -N[Q]) { if (MErrval%2 != 0) Errval=((Int32)MErrval-1)/2; // 1 becomes 0, 3 becomes 1, 5 becomes 2 else Errval=-(Int32)MErrval/2 - 1; // 0 becomes -1, 2 becomes -2, 4 becomes -3 } else { if (MErrval%2 == 0) Errval=(Int32)MErrval/2; // 0 becomes 0, 2 becomes 1, 4 becomes 2 else Errval=-((Int32)MErrval + 1)/2; // 1 becomes -1, 3 becomes -2 } updateErrval=Errval; // NB. Before dequantization and sign correction deQuantizeErrval(NEAR,Errval);//cerr << "\t\tErrval SIGN uncorrected = " << Errval << endl; if (SIGN < 0) Errval=-Errval; // if "context type" was negative//cerr << "\t\tErrval result = " << Errval << endl; Rx=Px+Errval; // modulo(RANGE*(2*NEAR+1)) as per F.1 Item 14 // (NB. Is this really the reverse of the encoding procedure ???) if (Rx < -NEAR) Rx+=RANGE*(2*NEAR+1); else if (Rx > MAXVAL+NEAR) Rx-=RANGE*(2*NEAR+1); clampPredictedValue(Rx,MAXVAL); // Apply inverse point transform and mapping table when implemented thisRow[col]=(Uint16)Rx;//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl; } else { // compressing ... Int32 Ix = thisRow[col]; // Input value - not Uint16 to allow overrange before clamping//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl; Errval = Ix - Px; // watch this for bad unsigned->signed conversion :(//cerr << "\t\tErrval start = " << Errval << endl; if (SIGN < 0) Errval=-Errval; // if "context type" was negative//cerr << "\t\tErrval SIGN corrected = " << Errval << endl; if (NEAR > 0) { // For near-lossless, quantize Errval and derive reconstructed value (A.4.4) quantizeErrval(NEAR,Errval); // Replace with the reconstructed value the decoder will have // (obviously if in lossless mode there will be no difference) Rx=Px+SIGN*Errval*(2*NEAR+1); clampPredictedValue(Rx,MAXVAL); thisRow[col]=(Uint16)Rx; } // Modulo reduction of the prediction error (A.4.5) if (Errval < 0) Errval=Errval+RANGE; if (Errval >= (RANGE+1)/2) Errval=Errval-RANGE;//cerr << "\t\tErrval modulo " << RANGE << " = " << Errval << endl; updateErrval=Errval; // NB. After sign correction but before mapping // Prediction error encoding (A.5) // Golomb k parameter determined already outside decompress/compress test // Map Errval to non-negative (A.5.2) ... if (NEAR == 0 && k == 0 && 2*B[Q] <= -N[Q]) { if (Errval >= 0) MErrval = 2*Errval + 1; // 0 becomes 1, 1 becomes 3, 2 becomes 5 else MErrval = -2*(Errval+1); // -1 becomes 0, -2 becomes 2, -3 becomes 4 } else { if (Errval >= 0) MErrval = 2*Errval; // 0 becomes 0, 1 becomes 2, 2 becomes 4 else MErrval = -2*Errval - 1; // -1 becomes 1, -2 becomes 3 }//cerr << "\t\tMErrval = " << MErrval << endl; encodeMappedErrvalWithGolomb(k,LIMIT,qbpp,MErrval,out); } // Update variables (A.6) ...//cerr << "\t\tUpdate variables with error updateErrval = " << updateErrval << endl;//cerr << "\t\tA[Q] old = " << A[Q] << endl;//cerr << "\t\tB[Q] old = " << B[Q] << endl;//cerr << "\t\tC[Q] old = " << C[Q] << endl;//cerr << "\t\tN[Q] old = " << N[Q] << endl; // A.6.1 Use the signed error after modulo reduction (figure A.12 note). which is updateErrval B[Q]=B[Q]+updateErrval*(2*NEAR+1); A[Q]=A[Q]+Abs(updateErrval); if (N[Q] == RESET) { A[Q]=A[Q]>>1; B[Q]=B[Q]>>1; N[Q]=N[Q]>>1; } ++N[Q];//cerr << "\t\tA[Q] updated = " << A[Q] << endl;//cerr << "\t\tB[Q] updated = " << B[Q] << endl;//cerr << "\t\tC[Q] updated = " << C[Q] << endl;//cerr << "\t\tN[Q] updated = " << N[Q] << endl; // A.6.2 Context dependent bias cancellation ... if (B[Q] <= -N[Q]) { B[Q]+=N[Q]; if (C[Q] > MIN_C) --C[Q]; if (B[Q] <= -N[Q]) B[Q]=-N[Q]+1; } else if (B[Q] > 0) { B[Q]-=N[Q]; if (C[Q] < MAX_C) ++C[Q]; if (B[Q] > 0) B[Q]=0; }//cerr << "\t\tA[Q] bias cancelled = " << A[Q] << endl;//cerr << "\t\tB[Q] bias cancelled = " << B[Q] << endl;//cerr << "\t\tC[Q] bias cancelled = " << C[Q] << endl;//cerr << "\t\tN[Q] bias cancelled = " << N[Q] << endl; } } if (decompressing) { if (!writeRow(out,thisRow,COLUMNS,bpp)) Assert(0); } Uint16 *tmpRow=thisRow; thisRow=prevRow; prevRow=tmpRow; } if (!decompressing) writeBitFlush(out); if (!decompressing && useJPEGmarkers) { writeEOI(out); } if (rowA) delete[] rowA; if (rowB) delete[] rowB; if (A) delete[] A; if (B) delete[] B; if (C) delete[] C; if (N) delete[] N; return success ? 0 : 1;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -