static bool ReadBlock(JPEGCompressor *self,JPEGBlock *block,int comp) { int dcindex=self->jpeg.scancomponents[comp].dcindex; int acindex=self->jpeg.scancomponents[comp].acindex; int dcmagnitude=ReadHuffmanCode(&self->bitstream,&self->dctables[dcindex]); if(dcmagnitude<0) return false; int dcremainder=ReadBitString(&self->bitstream,dcmagnitude); if(dcremainder<0) return false; int delta=DecodeValue(dcmagnitude,dcremainder); block->c[0]=self->predicted[comp]+delta; self->predicted[comp]+=delta; int coeff=1; while(coeff<64) { int val=ReadHuffmanCode(&self->bitstream,&self->actables[acindex]); if(val<0) return false; if(val==0x00) break; int zeroes=val>>4; int acmagnitude=val&0x0f; int acremainder=ReadBitString(&self->bitstream,acmagnitude); if(acremainder<0) return false; // TODO: range checks for(int i=0;i<zeroes;i++) block->c[coeff++]=0; block->c[coeff++]=DecodeValue(acmagnitude,acremainder); } for(int i=coeff;i<64;i++) block->c[i]=0; block->eob=coeff-1; return true; }
void DecompressData(FILE *fh,uint8_t *buf,uint32_t size, int typeshift,int literalshift,int lengthshift1,int lengthshift2,int offsetshift1,int offsetshift2) { RangeDecoder dec; InitializeRangeDecoder(&dec,STDIOReadFunction,fh); int typeweight=0x800; int lengthweights1[32],lengthweights2[32]; int offsetweights1[32],offsetweights2[32]; for(int i=0;i<32;i++) lengthweights1[i]=lengthweights2[i]=offsetweights1[i]=offsetweights2[i]=0x800; int literalbitweights[256]; for(int i=0;i<256;i++) literalbitweights[i]=0x800; int pos=0; while(pos<size) { int length,offs; if(ReadDynamicBit(&dec,&typeweight,typeshift)==1) { int length=(ReadUniversalCode2(&dec,size-pos-3,lengthweights1,lengthshift1,lengthweights2,lengthshift2)+3); int offs=(ReadUniversalCode2(&dec,pos-1,offsetweights1,offsetshift1,offsetweights2,offsetshift2)+1); CopyMemory(&buf[pos],&buf[pos-offs],length); pos+=length; } else { buf[pos++]=ReadBitString(&dec,8,literalbitweights,literalshift); } } }
void CObjectIStreamJson::SkipBitString(void) { CBitString obj; ReadBitString(obj); }