OLD | NEW |
1 // Copyright 2015 PDFium Authors. All rights reserved. | 1 // Copyright 2015 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fxcodec/jbig2/JBig2_GrdProc.h" | 7 #include "core/fxcodec/jbig2/JBig2_GrdProc.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 } | 64 } |
65 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( | 65 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( |
66 CJBig2_ArithDecoder* pArithDecoder, | 66 CJBig2_ArithDecoder* pArithDecoder, |
67 JBig2ArithCtx* gbContext) { | 67 JBig2ArithCtx* gbContext) { |
68 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); | 68 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); |
69 if (!GBREG->m_pData) | 69 if (!GBREG->m_pData) |
70 return nullptr; | 70 return nullptr; |
71 | 71 |
72 FX_BOOL LTP = FALSE; | 72 FX_BOOL LTP = FALSE; |
73 uint8_t* pLine = GBREG->m_pData; | 73 uint8_t* pLine = GBREG->m_pData; |
74 int32_t nStride = GBREG->m_nStride; | 74 int32_t nStride = GBREG->stride(); |
75 int32_t nStride2 = nStride << 1; | 75 int32_t nStride2 = nStride << 1; |
76 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 76 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
77 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 77 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
78 uint32_t height = GBH & 0x7fffffff; | 78 uint32_t height = GBH & 0x7fffffff; |
79 for (uint32_t h = 0; h < height; h++) { | 79 for (uint32_t h = 0; h < height; h++) { |
80 if (TPGDON) | 80 if (TPGDON) |
81 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); | 81 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); |
82 if (LTP) { | 82 if (LTP) { |
83 GBREG->copyLine(h, h - 1); | 83 GBREG->copyLine(h, h - 1); |
84 } else { | 84 } else { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 | 190 |
191 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( | 191 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( |
192 CJBig2_ArithDecoder* pArithDecoder, | 192 CJBig2_ArithDecoder* pArithDecoder, |
193 JBig2ArithCtx* gbContext) { | 193 JBig2ArithCtx* gbContext) { |
194 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); | 194 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); |
195 if (!GBREG->m_pData) | 195 if (!GBREG->m_pData) |
196 return nullptr; | 196 return nullptr; |
197 | 197 |
198 FX_BOOL LTP = FALSE; | 198 FX_BOOL LTP = FALSE; |
199 uint8_t* pLine = GBREG->m_pData; | 199 uint8_t* pLine = GBREG->m_pData; |
200 int32_t nStride = GBREG->m_nStride; | 200 int32_t nStride = GBREG->stride(); |
201 int32_t nStride2 = nStride << 1; | 201 int32_t nStride2 = nStride << 1; |
202 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 202 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
203 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 203 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
204 for (uint32_t h = 0; h < GBH; h++) { | 204 for (uint32_t h = 0; h < GBH; h++) { |
205 if (TPGDON) | 205 if (TPGDON) |
206 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); | 206 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); |
207 if (LTP) { | 207 if (LTP) { |
208 GBREG->copyLine(h, h - 1); | 208 GBREG->copyLine(h, h - 1); |
209 } else { | 209 } else { |
210 if (h > 1) { | 210 if (h > 1) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 313 |
314 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( | 314 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( |
315 CJBig2_ArithDecoder* pArithDecoder, | 315 CJBig2_ArithDecoder* pArithDecoder, |
316 JBig2ArithCtx* gbContext) { | 316 JBig2ArithCtx* gbContext) { |
317 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); | 317 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); |
318 if (!GBREG->m_pData) | 318 if (!GBREG->m_pData) |
319 return nullptr; | 319 return nullptr; |
320 | 320 |
321 FX_BOOL LTP = FALSE; | 321 FX_BOOL LTP = FALSE; |
322 uint8_t* pLine = GBREG->m_pData; | 322 uint8_t* pLine = GBREG->m_pData; |
323 int32_t nStride = GBREG->m_nStride; | 323 int32_t nStride = GBREG->stride(); |
324 int32_t nStride2 = nStride << 1; | 324 int32_t nStride2 = nStride << 1; |
325 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 325 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
326 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 326 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
327 for (uint32_t h = 0; h < GBH; h++) { | 327 for (uint32_t h = 0; h < GBH; h++) { |
328 if (TPGDON) | 328 if (TPGDON) |
329 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); | 329 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); |
330 if (LTP) { | 330 if (LTP) { |
331 GBREG->copyLine(h, h - 1); | 331 GBREG->copyLine(h, h - 1); |
332 } else { | 332 } else { |
333 if (h > 1) { | 333 if (h > 1) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 434 |
435 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( | 435 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( |
436 CJBig2_ArithDecoder* pArithDecoder, | 436 CJBig2_ArithDecoder* pArithDecoder, |
437 JBig2ArithCtx* gbContext) { | 437 JBig2ArithCtx* gbContext) { |
438 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); | 438 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH)); |
439 if (!GBREG->m_pData) | 439 if (!GBREG->m_pData) |
440 return nullptr; | 440 return nullptr; |
441 | 441 |
442 FX_BOOL LTP = FALSE; | 442 FX_BOOL LTP = FALSE; |
443 uint8_t* pLine = GBREG->m_pData; | 443 uint8_t* pLine = GBREG->m_pData; |
444 int32_t nStride = GBREG->m_nStride; | 444 int32_t nStride = GBREG->stride(); |
445 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 445 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
446 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 446 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
447 for (uint32_t h = 0; h < GBH; h++) { | 447 for (uint32_t h = 0; h < GBH; h++) { |
448 if (TPGDON) | 448 if (TPGDON) |
449 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); | 449 LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); |
450 if (LTP) { | 450 if (LTP) { |
451 GBREG->copyLine(h, h - 1); | 451 GBREG->copyLine(h, h - 1); |
452 } else { | 452 } else { |
453 if (h > 0) { | 453 if (h > 0) { |
454 uint8_t* pLine1 = pLine - nStride; | 454 uint8_t* pLine1 = pLine - nStride; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 } else { | 595 } else { |
596 if (UseTemplate23Opt3()) { | 596 if (UseTemplate23Opt3()) { |
597 m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder, | 597 m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder, |
598 m_gbContext, pPause); | 598 m_gbContext, pPause); |
599 } else { | 599 } else { |
600 m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder, | 600 m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder, |
601 m_gbContext, pPause); | 601 m_gbContext, pPause); |
602 } | 602 } |
603 } | 603 } |
604 m_ReplaceRect.left = 0; | 604 m_ReplaceRect.left = 0; |
605 m_ReplaceRect.right = pImage->m_nWidth; | 605 m_ReplaceRect.right = pImage->width(); |
606 m_ReplaceRect.top = iline; | 606 m_ReplaceRect.top = iline; |
607 m_ReplaceRect.bottom = m_loopIndex; | 607 m_ReplaceRect.bottom = m_loopIndex; |
608 if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) { | 608 if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) { |
609 m_loopIndex = 0; | 609 m_loopIndex = 0; |
610 } | 610 } |
611 return m_ProssiveStatus; | 611 return m_ProssiveStatus; |
612 } | 612 } |
613 | 613 |
614 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage, | 614 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage, |
615 CJBig2_BitStream* pStream, | 615 CJBig2_BitStream* pStream, |
616 IFX_Pause* pPause) { | 616 IFX_Pause* pPause) { |
617 int bitpos, i; | 617 int bitpos, i; |
618 *pImage = new CJBig2_Image(GBW, GBH); | 618 *pImage = new CJBig2_Image(GBW, GBH); |
619 if (!(*pImage)->m_pData) { | 619 if (!(*pImage)->m_pData) { |
620 delete (*pImage); | 620 delete (*pImage); |
621 (*pImage) = nullptr; | 621 (*pImage) = nullptr; |
622 m_ProssiveStatus = FXCODEC_STATUS_ERROR; | 622 m_ProssiveStatus = FXCODEC_STATUS_ERROR; |
623 return m_ProssiveStatus; | 623 return m_ProssiveStatus; |
624 } | 624 } |
625 bitpos = (int)pStream->getBitPos(); | 625 bitpos = (int)pStream->getBitPos(); |
626 FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos, | 626 FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos, |
627 (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride); | 627 (*pImage)->m_pData, GBW, GBH, (*pImage)->stride()); |
628 pStream->setBitPos(bitpos); | 628 pStream->setBitPos(bitpos); |
629 for (i = 0; (uint32_t)i < (*pImage)->m_nStride * GBH; i++) { | 629 for (i = 0; (uint32_t)i < (*pImage)->stride() * GBH; i++) { |
630 (*pImage)->m_pData[i] = ~(*pImage)->m_pData[i]; | 630 (*pImage)->m_pData[i] = ~(*pImage)->m_pData[i]; |
631 } | 631 } |
632 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH; | 632 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH; |
633 return m_ProssiveStatus; | 633 return m_ProssiveStatus; |
634 } | 634 } |
635 | 635 |
636 FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause) { | 636 FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause) { |
637 if (m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE) | 637 if (m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE) |
638 return m_ProssiveStatus; | 638 return m_ProssiveStatus; |
639 | 639 |
640 if (m_DecodeType != 1) { | 640 if (m_DecodeType != 1) { |
641 m_ProssiveStatus = FXCODEC_STATUS_ERROR; | 641 m_ProssiveStatus = FXCODEC_STATUS_ERROR; |
642 return m_ProssiveStatus; | 642 return m_ProssiveStatus; |
643 } | 643 } |
644 | 644 |
645 return decode_Arith(pPause); | 645 return decode_Arith(pPause); |
646 } | 646 } |
647 | 647 |
648 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( | 648 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( |
649 CJBig2_Image* pImage, | 649 CJBig2_Image* pImage, |
650 CJBig2_ArithDecoder* pArithDecoder, | 650 CJBig2_ArithDecoder* pArithDecoder, |
651 JBig2ArithCtx* gbContext, | 651 JBig2ArithCtx* gbContext, |
652 IFX_Pause* pPause) { | 652 IFX_Pause* pPause) { |
653 if (!m_pLine) { | 653 if (!m_pLine) { |
654 m_pLine = pImage->m_pData; | 654 m_pLine = pImage->m_pData; |
655 } | 655 } |
656 int32_t nStride = pImage->m_nStride; | 656 int32_t nStride = pImage->stride(); |
657 int32_t nStride2 = nStride << 1; | 657 int32_t nStride2 = nStride << 1; |
658 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 658 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
659 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 659 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
660 uint32_t height = GBH & 0x7fffffff; | 660 uint32_t height = GBH & 0x7fffffff; |
661 for (; m_loopIndex < height; m_loopIndex++) { | 661 for (; m_loopIndex < height; m_loopIndex++) { |
662 if (TPGDON) | 662 if (TPGDON) |
663 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); | 663 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); |
664 if (m_LTP) { | 664 if (m_LTP) { |
665 pImage->copyLine(m_loopIndex, m_loopIndex - 1); | 665 pImage->copyLine(m_loopIndex, m_loopIndex - 1); |
666 } else { | 666 } else { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 } | 784 } |
785 | 785 |
786 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( | 786 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( |
787 CJBig2_Image* pImage, | 787 CJBig2_Image* pImage, |
788 CJBig2_ArithDecoder* pArithDecoder, | 788 CJBig2_ArithDecoder* pArithDecoder, |
789 JBig2ArithCtx* gbContext, | 789 JBig2ArithCtx* gbContext, |
790 IFX_Pause* pPause) { | 790 IFX_Pause* pPause) { |
791 if (!m_pLine) { | 791 if (!m_pLine) { |
792 m_pLine = pImage->m_pData; | 792 m_pLine = pImage->m_pData; |
793 } | 793 } |
794 int32_t nStride = pImage->m_nStride; | 794 int32_t nStride = pImage->stride(); |
795 int32_t nStride2 = nStride << 1; | 795 int32_t nStride2 = nStride << 1; |
796 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 796 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
797 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 797 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
798 for (; m_loopIndex < GBH; m_loopIndex++) { | 798 for (; m_loopIndex < GBH; m_loopIndex++) { |
799 if (TPGDON) | 799 if (TPGDON) |
800 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); | 800 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); |
801 if (m_LTP) { | 801 if (m_LTP) { |
802 pImage->copyLine(m_loopIndex, m_loopIndex - 1); | 802 pImage->copyLine(m_loopIndex, m_loopIndex - 1); |
803 } else { | 803 } else { |
804 if (m_loopIndex > 1) { | 804 if (m_loopIndex > 1) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 } | 917 } |
918 | 918 |
919 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( | 919 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( |
920 CJBig2_Image* pImage, | 920 CJBig2_Image* pImage, |
921 CJBig2_ArithDecoder* pArithDecoder, | 921 CJBig2_ArithDecoder* pArithDecoder, |
922 JBig2ArithCtx* gbContext, | 922 JBig2ArithCtx* gbContext, |
923 IFX_Pause* pPause) { | 923 IFX_Pause* pPause) { |
924 if (!m_pLine) { | 924 if (!m_pLine) { |
925 m_pLine = pImage->m_pData; | 925 m_pLine = pImage->m_pData; |
926 } | 926 } |
927 int32_t nStride = pImage->m_nStride; | 927 int32_t nStride = pImage->stride(); |
928 int32_t nStride2 = nStride << 1; | 928 int32_t nStride2 = nStride << 1; |
929 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 929 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
930 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 930 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
931 for (; m_loopIndex < GBH; m_loopIndex++) { | 931 for (; m_loopIndex < GBH; m_loopIndex++) { |
932 if (TPGDON) | 932 if (TPGDON) |
933 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); | 933 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); |
934 if (m_LTP) { | 934 if (m_LTP) { |
935 pImage->copyLine(m_loopIndex, m_loopIndex - 1); | 935 pImage->copyLine(m_loopIndex, m_loopIndex - 1); |
936 } else { | 936 } else { |
937 if (m_loopIndex > 1) { | 937 if (m_loopIndex > 1) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 } | 1050 } |
1051 | 1051 |
1052 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( | 1052 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( |
1053 CJBig2_Image* pImage, | 1053 CJBig2_Image* pImage, |
1054 CJBig2_ArithDecoder* pArithDecoder, | 1054 CJBig2_ArithDecoder* pArithDecoder, |
1055 JBig2ArithCtx* gbContext, | 1055 JBig2ArithCtx* gbContext, |
1056 IFX_Pause* pPause) { | 1056 IFX_Pause* pPause) { |
1057 if (!m_pLine) | 1057 if (!m_pLine) |
1058 m_pLine = pImage->m_pData; | 1058 m_pLine = pImage->m_pData; |
1059 | 1059 |
1060 int32_t nStride = pImage->m_nStride; | 1060 int32_t nStride = pImage->stride(); |
1061 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; | 1061 int32_t nLineBytes = ((GBW + 7) >> 3) - 1; |
1062 int32_t nBitsLeft = GBW - (nLineBytes << 3); | 1062 int32_t nBitsLeft = GBW - (nLineBytes << 3); |
1063 for (; m_loopIndex < GBH; m_loopIndex++) { | 1063 for (; m_loopIndex < GBH; m_loopIndex++) { |
1064 if (TPGDON) | 1064 if (TPGDON) |
1065 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); | 1065 m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); |
1066 if (m_LTP) { | 1066 if (m_LTP) { |
1067 pImage->copyLine(m_loopIndex, m_loopIndex - 1); | 1067 pImage->copyLine(m_loopIndex, m_loopIndex - 1); |
1068 } else { | 1068 } else { |
1069 if (m_loopIndex > 0) { | 1069 if (m_loopIndex > 0) { |
1070 uint8_t* pLine1 = m_pLine - nStride; | 1070 uint8_t* pLine1 = m_pLine - nStride; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 } | 1155 } |
1156 if (pPause && pPause->NeedToPauseNow()) { | 1156 if (pPause && pPause->NeedToPauseNow()) { |
1157 m_loopIndex++; | 1157 m_loopIndex++; |
1158 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | 1158 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
1159 return FXCODEC_STATUS_DECODE_TOBECONTINUE; | 1159 return FXCODEC_STATUS_DECODE_TOBECONTINUE; |
1160 } | 1160 } |
1161 } | 1161 } |
1162 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH; | 1162 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH; |
1163 return FXCODEC_STATUS_DECODE_FINISH; | 1163 return FXCODEC_STATUS_DECODE_FINISH; |
1164 } | 1164 } |
OLD | NEW |