~ubuntu-branches/ubuntu/vivid/unrar-nonfree/vivid

« back to all changes in this revision

Viewing changes to unpack50.cpp

  • Committer: Package Import Robot
  • Author(s): Martin Meredith
  • Date: 2015-02-03 12:58:01 UTC
  • mfrom: (1.1.18) (5.1.18 sid)
  • Revision ID: package-import@ubuntu.com-20150203125801-od6ev8cqy1er51vz
Tags: 1:5.2.5-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
177
177
  Filter.Type=Inp.fgetbits()>>13;
178
178
  Inp.faddbits(3);
179
179
 
180
 
  if (Filter.Type==FILTER_DELTA || Filter.Type==FILTER_AUDIO)
 
180
  if (Filter.Type==FILTER_DELTA)
181
181
  {
182
182
    Filter.Channels=(Inp.fgetbits()>>11)+1;
183
183
    Inp.faddbits(5);
184
184
  }
185
185
 
186
 
  if (Filter.Type==FILTER_RGB)
187
 
  {
188
 
    Filter.Channels=3;
189
 
    Filter.Width=Inp.fgetbits()+1;
190
 
    Inp.faddbits(16);
191
 
    Filter.PosR=Inp.fgetbits()>>14;
192
 
    Inp.faddbits(2);
193
 
  }
194
 
 
195
186
  return true;
196
187
}
197
188
 
233
224
  }
234
225
  else
235
226
    DataSize=ReadTop;
236
 
  int ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize);
237
 
  if (ReadCode>0)
 
227
  int ReadCode=0;
 
228
  if (BitInput::MAX_SIZE!=DataSize)
 
229
    ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize);
 
230
  if (ReadCode>0) // Can be also -1.
238
231
    ReadTop+=ReadCode;
239
232
  ReadBorder=ReadTop-30;
240
233
  BlockHeader.BlockStart=Inp.InAddr;
241
234
  if (BlockHeader.BlockSize!=-1) // '-1' means not defined yet.
 
235
  {
 
236
    // We may need to quit from main extraction loop and read new block header
 
237
    // and trees earlier than data in input buffer ends.
242
238
    ReadBorder=Min(ReadBorder,BlockHeader.BlockStart+BlockHeader.BlockSize-1);
 
239
  }
243
240
  return ReadCode!=-1;
244
241
}
245
242
 
386
383
}
387
384
 
388
385
 
389
 
uint Unpack::FilterItanium_GetBits(byte *Data,int BitPos,int BitCount)
390
 
{
391
 
  int InAddr=BitPos/8;
392
 
  int InBit=BitPos&7;
393
 
  uint BitField=(uint)Data[InAddr++];
394
 
  BitField|=(uint)Data[InAddr++] << 8;
395
 
  BitField|=(uint)Data[InAddr++] << 16;
396
 
  BitField|=(uint)Data[InAddr] << 24;
397
 
  BitField >>= InBit;
398
 
  return(BitField & (0xffffffff>>(32-BitCount)));
399
 
}
400
 
 
401
 
 
402
 
void Unpack::FilterItanium_SetBits(byte *Data,uint BitField,int BitPos,int BitCount)
403
 
{
404
 
  int InAddr=BitPos/8;
405
 
  int InBit=BitPos&7;
406
 
  uint AndMask=0xffffffff>>(32-BitCount);
407
 
  AndMask=~(AndMask<<InBit);
408
 
 
409
 
  BitField<<=InBit;
410
 
 
411
 
  for (uint I=0;I<4;I++)
412
 
  {
413
 
    Data[InAddr+I]&=AndMask;
414
 
    Data[InAddr+I]|=BitField;
415
 
    AndMask=(AndMask>>8)|0xff000000;
416
 
    BitField>>=8;
417
 
  }
418
 
}
419
 
 
420
 
 
421
 
inline uint GetFiltData32(byte *Data)
422
 
{
423
 
#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
424
 
  uint Value=GET_UINT32((uint)Data[0]|((uint)Data[1]<<8)|((uint)Data[2]<<16)|((uint)Data[3]<<24));
425
 
#else
426
 
  uint Value=GET_UINT32(*(uint32 *)Data);
427
 
#endif
428
 
  return Value;
429
 
}
430
 
 
431
 
 
432
 
inline void SetFiltData32(byte *Data,uint Value)
433
 
{
434
 
#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
435
 
   Data[0]=(byte)Value;
436
 
   Data[1]=(byte)(Value>>8);
437
 
   Data[2]=(byte)(Value>>16);
438
 
   Data[3]=(byte)(Value>>24);
439
 
#else
440
 
   *(int32 *)Data=Value;
441
 
#endif
442
 
}
443
 
 
444
 
 
445
386
byte* Unpack::ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt)
446
387
{
447
388
  byte *SrcData=Data;
461
402
          if (CurByte==0xe8 || CurByte==CmpByte2)
462
403
          {
463
404
            uint Offset=(CurPos+FileOffset)%FileSize;
464
 
            uint Addr=GetFiltData32(Data);
 
405
            uint Addr=RawGet4(Data);
465
406
 
466
407
            // We check 0x80000000 bit instead of '< 0' comparison
467
408
            // not assuming int32 presence or uint size and endianness.
468
409
            if ((Addr & 0x80000000)!=0)              // Addr<0
469
410
            {
470
411
              if (((Addr+Offset) & 0x80000000)==0)   // Addr+Offset>=0
471
 
                SetFiltData32(Data,Addr+FileSize);
 
412
                RawPut4(Addr+FileSize,Data);
472
413
            }
473
414
            else
474
415
              if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize
475
 
                SetFiltData32(Data,Addr-Offset);
 
416
                RawPut4(Addr-Offset,Data);
476
417
 
477
418
            Data+=4;
478
419
            CurPos+=4;
497
438
        }
498
439
      }
499
440
      return SrcData;
500
 
    case FILTER_ITANIUM:
501
 
      {
502
 
        uint FileOffset=(uint)WrittenFileSize;
503
 
 
504
 
        uint CurPos=0;
505
 
 
506
 
        FileOffset>>=4;
507
 
 
508
 
        while ((int)CurPos<(int)DataSize-21)
509
 
        {
510
 
          int Byte=(Data[0]&0x1f)-0x10;
511
 
          if (Byte>=0)
512
 
          {
513
 
            static byte Masks[16]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};
514
 
            byte CmdMask=Masks[Byte];
515
 
            if (CmdMask!=0)
516
 
              for (int I=0;I<=2;I++)
517
 
                if (CmdMask & (1<<I))
518
 
                {
519
 
                  int StartPos=I*41+5;
520
 
                  int OpType=FilterItanium_GetBits(Data,StartPos+37,4);
521
 
                  if (OpType==5)
522
 
                  {
523
 
                    int Offset=FilterItanium_GetBits(Data,StartPos+13,20);
524
 
                    FilterItanium_SetBits(Data,(Offset-FileOffset)&0xfffff,StartPos+13,20);
525
 
                  }
526
 
                }
527
 
          }
528
 
          Data+=16;
529
 
          CurPos+=16;
530
 
          FileOffset++;
531
 
        }
532
 
      }
533
 
      return SrcData;
534
 
    case FILTER_AUDIO:
535
 
      {
536
 
        uint Channels=Flt->Channels;
537
 
 
538
 
        byte *SrcData=Data;
539
 
 
540
 
        FilterDstMemory.Alloc(DataSize);
541
 
        byte *DstData=&FilterDstMemory[0];
542
 
        
543
 
        for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
544
 
        {
545
 
          uint PrevByte=0,PrevDelta=0,Dif[7];
546
 
          int D1=0,D2=0,D3;
547
 
          int K1=0,K2=0,K3=0;
548
 
          memset(Dif,0,sizeof(Dif));
549
 
 
550
 
          for (uint I=CurChannel,ByteCount=0;I<DataSize;I+=Channels,ByteCount++)
551
 
          {
552
 
            D3=D2;
553
 
            D2=PrevDelta-D1;
554
 
            D1=PrevDelta;
555
 
 
556
 
            uint Predicted=8*PrevByte+K1*D1+K2*D2+K3*D3;
557
 
            Predicted=(Predicted>>3) & 0xff;
558
 
 
559
 
            uint CurByte=*(SrcData++);
560
 
 
561
 
            Predicted-=CurByte;
562
 
            DstData[I]=Predicted;
563
 
            PrevDelta=(signed char)(Predicted-PrevByte);
564
 
            PrevByte=Predicted;
565
 
 
566
 
            int D=((signed char)CurByte)<<3;
567
 
 
568
 
            Dif[0]+=abs(D);
569
 
            Dif[1]+=abs(D-D1);
570
 
            Dif[2]+=abs(D+D1);
571
 
            Dif[3]+=abs(D-D2);
572
 
            Dif[4]+=abs(D+D2);
573
 
            Dif[5]+=abs(D-D3);
574
 
            Dif[6]+=abs(D+D3);
575
 
 
576
 
            if ((ByteCount & 0x1f)==0)
577
 
            {
578
 
              uint MinDif=Dif[0],NumMinDif=0;
579
 
              Dif[0]=0;
580
 
              for (uint J=1;J<ASIZE(Dif);J++)
581
 
              {
582
 
                if (Dif[J]<MinDif)
583
 
                {
584
 
                  MinDif=Dif[J];
585
 
                  NumMinDif=J;
586
 
                }
587
 
                Dif[J]=0;
588
 
              }
589
 
              switch(NumMinDif)
590
 
              {
591
 
                case 1: if (K1>=-16) K1--; break;
592
 
                case 2: if (K1 < 16) K1++; break;
593
 
                case 3: if (K2>=-16) K2--; break;
594
 
                case 4: if (K2 < 16) K2++; break;
595
 
                case 5: if (K3>=-16) K3--; break;
596
 
                case 6: if (K3 < 16) K3++; break;
597
 
              }
598
 
            }
599
 
          }
600
 
        }
601
 
        return DstData;
602
 
      }
603
441
    case FILTER_DELTA:
604
442
      {
605
443
        uint Channels=Flt->Channels,SrcPos=0;
617
455
        }
618
456
        return DstData;
619
457
      }
620
 
    case FILTER_RGB:
621
 
      {
622
 
        uint Width=Flt->Width,PosR=Flt->PosR;
623
 
 
624
 
        byte *SrcData=Data;
625
 
 
626
 
        FilterDstMemory.Alloc(DataSize);
627
 
        byte *DstData=&FilterDstMemory[0];
628
 
        
629
 
        const int Channels=3;
630
 
 
631
 
        for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
632
 
        {
633
 
          uint PrevByte=0;
634
 
 
635
 
          for (uint I=CurChannel;I<DataSize;I+=Channels)
636
 
          {
637
 
            uint Predicted;
638
 
            int UpperPos=I-Width;
639
 
            if (UpperPos>=3)
640
 
            {
641
 
              byte *UpperData=DstData+UpperPos;
642
 
              uint UpperByte=*UpperData;
643
 
              uint UpperLeftByte=*(UpperData-3);
644
 
              Predicted=PrevByte+UpperByte-UpperLeftByte;
645
 
              int pa=abs((int)(Predicted-PrevByte));
646
 
              int pb=abs((int)(Predicted-UpperByte));
647
 
              int pc=abs((int)(Predicted-UpperLeftByte));
648
 
              if (pa<=pb && pa<=pc)
649
 
                Predicted=PrevByte;
650
 
              else
651
 
                if (pb<=pc)
652
 
                  Predicted=UpperByte;
653
 
                else
654
 
                  Predicted=UpperLeftByte;
655
 
            }
656
 
            else
657
 
              Predicted=PrevByte;
658
 
            DstData[I]=PrevByte=(byte)(Predicted-*(SrcData++));
659
 
          }
660
 
        }
661
 
        for (uint I=PosR,Border=DataSize-2;I<Border;I+=3)
662
 
        {
663
 
          byte G=DstData[I+1];
664
 
          DstData[I]+=G;
665
 
          DstData[I+2]+=G;
666
 
        }
667
 
        return DstData;
668
 
      }
669
458
 
670
459
  }
671
460
  return NULL;
781
570
      else
782
571
      {
783
572
        ZeroCount+=2;
784
 
        while (ZeroCount-- > 0 && I<sizeof(BitLength)/sizeof(BitLength[0]))
 
573
        while (ZeroCount-- > 0 && I<ASIZE(BitLength))
785
574
          BitLength[I++]=0;
786
575
        I--;
787
576
      }
798
587
  {
799
588
    if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-5)
800
589
      if (!UnpReadBuf())
801
 
        return(false);
 
590
        return false;
802
591
    int Number=DecodeNumber(Inp,&Tables.BD);
803
592
    if (Number<16)
804
593
    {
844
633
      }
845
634
  }
846
635
  if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
847
 
    return(false);
 
636
    return false;
848
637
  MakeDecodeTables(&Table[0],&Tables.LD,NC);
849
638
  MakeDecodeTables(&Table[NC],&Tables.DD,DC);
850
639
  MakeDecodeTables(&Table[NC+DC],&Tables.LDD,LDC);
851
640
  MakeDecodeTables(&Table[NC+DC+LDC],&Tables.RD,RC);
852
 
  return(true);
 
641
  return true;
853
642
}
854
643
 
855
644