177
177
Filter.Type=Inp.fgetbits()>>13;
180
if (Filter.Type==FILTER_DELTA || Filter.Type==FILTER_AUDIO)
180
if (Filter.Type==FILTER_DELTA)
182
182
Filter.Channels=(Inp.fgetbits()>>11)+1;
186
if (Filter.Type==FILTER_RGB)
189
Filter.Width=Inp.fgetbits()+1;
191
Filter.PosR=Inp.fgetbits()>>14;
235
226
DataSize=ReadTop;
236
int ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize);
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.
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);
243
240
return ReadCode!=-1;
389
uint Unpack::FilterItanium_GetBits(byte *Data,int BitPos,int BitCount)
393
uint BitField=(uint)Data[InAddr++];
394
BitField|=(uint)Data[InAddr++] << 8;
395
BitField|=(uint)Data[InAddr++] << 16;
396
BitField|=(uint)Data[InAddr] << 24;
398
return(BitField & (0xffffffff>>(32-BitCount)));
402
void Unpack::FilterItanium_SetBits(byte *Data,uint BitField,int BitPos,int BitCount)
406
uint AndMask=0xffffffff>>(32-BitCount);
407
AndMask=~(AndMask<<InBit);
411
for (uint I=0;I<4;I++)
413
Data[InAddr+I]&=AndMask;
414
Data[InAddr+I]|=BitField;
415
AndMask=(AndMask>>8)|0xff000000;
421
inline uint GetFiltData32(byte *Data)
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));
426
uint Value=GET_UINT32(*(uint32 *)Data);
432
inline void SetFiltData32(byte *Data,uint Value)
434
#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
436
Data[1]=(byte)(Value>>8);
437
Data[2]=(byte)(Value>>16);
438
Data[3]=(byte)(Value>>24);
440
*(int32 *)Data=Value;
445
386
byte* Unpack::ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt)
447
388
byte *SrcData=Data;
461
402
if (CurByte==0xe8 || CurByte==CmpByte2)
463
404
uint Offset=(CurPos+FileOffset)%FileSize;
464
uint Addr=GetFiltData32(Data);
405
uint Addr=RawGet4(Data);
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
470
411
if (((Addr+Offset) & 0x80000000)==0) // Addr+Offset>=0
471
SetFiltData32(Data,Addr+FileSize);
412
RawPut4(Addr+FileSize,Data);
474
415
if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize
475
SetFiltData32(Data,Addr-Offset);
416
RawPut4(Addr-Offset,Data);
502
uint FileOffset=(uint)WrittenFileSize;
508
while ((int)CurPos<(int)DataSize-21)
510
int Byte=(Data[0]&0x1f)-0x10;
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];
516
for (int I=0;I<=2;I++)
517
if (CmdMask & (1<<I))
520
int OpType=FilterItanium_GetBits(Data,StartPos+37,4);
523
int Offset=FilterItanium_GetBits(Data,StartPos+13,20);
524
FilterItanium_SetBits(Data,(Offset-FileOffset)&0xfffff,StartPos+13,20);
536
uint Channels=Flt->Channels;
540
FilterDstMemory.Alloc(DataSize);
541
byte *DstData=&FilterDstMemory[0];
543
for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
545
uint PrevByte=0,PrevDelta=0,Dif[7];
548
memset(Dif,0,sizeof(Dif));
550
for (uint I=CurChannel,ByteCount=0;I<DataSize;I+=Channels,ByteCount++)
556
uint Predicted=8*PrevByte+K1*D1+K2*D2+K3*D3;
557
Predicted=(Predicted>>3) & 0xff;
559
uint CurByte=*(SrcData++);
562
DstData[I]=Predicted;
563
PrevDelta=(signed char)(Predicted-PrevByte);
566
int D=((signed char)CurByte)<<3;
576
if ((ByteCount & 0x1f)==0)
578
uint MinDif=Dif[0],NumMinDif=0;
580
for (uint J=1;J<ASIZE(Dif);J++)
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;
603
441
case FILTER_DELTA:
605
443
uint Channels=Flt->Channels,SrcPos=0;
622
uint Width=Flt->Width,PosR=Flt->PosR;
626
FilterDstMemory.Alloc(DataSize);
627
byte *DstData=&FilterDstMemory[0];
629
const int Channels=3;
631
for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
635
for (uint I=CurChannel;I<DataSize;I+=Channels)
638
int UpperPos=I-Width;
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)
654
Predicted=UpperLeftByte;
658
DstData[I]=PrevByte=(byte)(Predicted-*(SrcData++));
661
for (uint I=PosR,Border=DataSize-2;I<Border;I+=3)
846
635
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
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);