int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder,unsigned char** ppBuffer,unsigned long* pSizeOfDecoderSpecificInfo) { BitStream* pBitStream = NULL; if((hEncoder == NULL) || (ppBuffer == NULL) || (pSizeOfDecoderSpecificInfo == NULL)) { return -1; } if(hEncoder->config.mpegVersion == MPEG2){ return -2; /* not supported */ } *pSizeOfDecoderSpecificInfo = 2; *ppBuffer = malloc(2); if(*ppBuffer != NULL){ memset(*ppBuffer,0,*pSizeOfDecoderSpecificInfo); pBitStream = OpenBitStream(*pSizeOfDecoderSpecificInfo, *ppBuffer); PutBit(pBitStream, hEncoder->config.aacObjectType, 5); PutBit(pBitStream, hEncoder->sampleRateIdx, 4); PutBit(pBitStream, hEncoder->numChannels, 4); CloseBitStream(pBitStream); return 0; } else { return -3; } }
static int WriteSCE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag) { int bits = 0; #ifndef DRM if (writeFlag) { /* write Single Element Channel (SCE) identifier */ PutBit(bitStream, ID_SCE, LEN_SE_ID); /* write the element identifier tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); } bits += LEN_SE_ID; bits += LEN_TAG; #endif /* Write an Individual Channel Stream element */ bits += WriteICS(coderInfo, bitStream, 0, objectType, writeFlag); return bits; }
static int WriteCPE(CoderInfo *coderInfoL, CoderInfo *coderInfoR, ChannelInfo *channelInfo, BitStream* bitStream, int objectType, int writeFlag) { int bits = 0; #ifndef DRM if (writeFlag) { /* write ID_CPE, single_element_channel() identifier */ PutBit(bitStream, ID_CPE, LEN_SE_ID); /* write the element_identifier_tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); /* common_window? */ PutBit(bitStream, channelInfo->common_window, LEN_COM_WIN); } bits += LEN_SE_ID; bits += LEN_TAG; bits += LEN_COM_WIN; #endif /* if common_window, write ics_info */ if (channelInfo->common_window) { int numWindows, maxSfb; bits += WriteICSInfo(coderInfoL, bitStream, objectType, channelInfo->common_window, writeFlag); numWindows = coderInfoL->num_window_groups; maxSfb = coderInfoL->max_sfb; if (writeFlag) { PutBit(bitStream, channelInfo->msInfo.is_present, LEN_MASK_PRES); if (channelInfo->msInfo.is_present == 1) { int g; int b; for (g=0;g<numWindows;g++) { for (b=0;b<maxSfb;b++) { PutBit(bitStream, channelInfo->msInfo.ms_used[g*maxSfb+b], LEN_MASK); } } } } bits += LEN_MASK_PRES; if (channelInfo->msInfo.is_present == 1) bits += (numWindows*maxSfb*LEN_MASK); } /* Write individual_channel_stream elements */ bits += WriteICS(coderInfoL, bitStream, channelInfo->common_window, objectType, writeFlag); bits += WriteICS(coderInfoR, bitStream, channelInfo->common_window, objectType, writeFlag); return bits; }
void HuffEncode (const unsigned char *in, unsigned char *out, int inlen, int *outlen) { int i, j, bitat; unsigned int t; #if _DEBUG_HUFFMAN unsigned char *buf; int tlen; #endif /* _DEBUG_HUFFMAN */ bitat = 0; for (i = 0; i < inlen; i++) { t = HuffLookup[in[i]].bits; for (j = 0; j < HuffLookup[in[i]].len; j++) { PutBit (out+1, bitat + HuffLookup[in[i]].len-j-1, t&1); t >>= 1; } bitat += HuffLookup[in[i]].len; } *outlen = 1 + (bitat + 7)/8; *out = 8 * ((*outlen)-1) - bitat; if (*outlen >= inlen+1) { *out = 0xff; memcpy (out+1, in, inlen); *outlen = inlen+1; } #if _DEBUG_HUFFMAN HuffIn += inlen; HuffOut += *outlen; HuffPrintf("in: %d out: %d ratio: %f\n", HuffIn, HuffOut, 1-(float)HuffOut/(float)HuffIn); CalcFreq(in, inlen); buf = (unsigned char *) malloc (inlen); HuffDecode (out, buf, *outlen, &tlen, inlen); if (tlen != inlen) Sys_Error("bogus compression"); for (i = 0; i < inlen; i++) { if (in[i] != buf[i]) Sys_Error("bogus compression"); } free (buf); #endif /* _DEBUG_HUFFMAN */ }
static int WriteLFE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag) { int bits = 0; if (writeFlag) { /* write ID_LFE, lfe_element_channel() identifier */ PutBit(bitStream, ID_LFE, LEN_SE_ID); /* write the element_identifier_tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); } bits += LEN_SE_ID; bits += LEN_TAG; /* Write an individual_channel_stream element */ bits += WriteICS(coderInfo, bitStream, 0, objectType, writeFlag); return bits; }
static int WriteFAACStr(BitStream *bitStream, char *version, int write) { int i; char str[200]; int len, padbits, count; int bitcnt; sprintf(str, "libfaac %s", version); len = strlen(str) + 1; padbits = (8 - ((bitStream->numBit + 7) % 8)) % 8; count = len + 3; bitcnt = LEN_SE_ID + 4 + ((count < 15) ? 0 : 8) + count * 8; if (!write) return bitcnt; PutBit(bitStream, ID_FIL, LEN_SE_ID); if (count < 15) { PutBit(bitStream, count, 4); } else { PutBit(bitStream, 15, 4); PutBit(bitStream, count - 14, 8); } PutBit(bitStream, 0, padbits); PutBit(bitStream, 0, 8); PutBit(bitStream, 0, 8); // just in case for (i = 0; i < len; i++) PutBit(bitStream, str[i], 8); PutBit(bitStream, 0, 8 - padbits); return bitcnt; }
void HuffEncode(unsigned char *in,unsigned char *out,int inlen,int *outlen) { int i,j,bitat; unsigned int t; bitat=0; for (i=0;i<inlen;i++) { t=HuffLookup[in[i]].bits; for (j=0;j<HuffLookup[in[i]].len;j++) { PutBit(out+1,bitat+HuffLookup[in[i]].len-j-1,t&1); t>>=1; } bitat+=HuffLookup[in[i]].len; } *outlen=1+(bitat+7)/8; *out=8*((*outlen)-1)-bitat; if(*outlen >= inlen+1) { *out=0xff; memcpy(out+1,in,inlen); *outlen=inlen+1; } #if _DEBUG HuffIn+=inlen; HuffOut+=*outlen; { unsigned char *buf; int tlen; buf=malloc(inlen); HuffDecode(out,buf,*outlen,&tlen); if(!tlen==inlen) Sys_Error("bogus compression"); for (i=0;i<inlen;i++) { if(in[i]!=buf[i]) Sys_Error("bogus compression"); } free(buf); } #endif }
void CJpegEncoder::WriteSOS() { PutByte(0xff); PutByte(0xda); WORD size = 6 + 2*ColorComponents; PutByte(size>>8); PutByte(size&0xff); PutByte(ColorComponents); // color components: 3 PutByte(1); // component id PutByte(0x00); // DC | AC huff tbl PutByte(2); // component id PutByte(0x11); // DC | AC huff tbl PutByte(3); // component id PutByte(0x11); // DC | AC huff tbl PutByte(0); // ss, first AC PutByte(63); // se, last AC PutByte(0); // ah | al static float cosuv[8][8][8][8]; // oh yeah, we don't need no fast dct :) for(int v = 0; v < 8; v++) for(int u = 0; u < 8; u++) for(int j = 0; j < 8; j++) for(int i = 0; i < 8; i++) cosuv[v][u][j][i] = (float)(cos((2*i+1)*u*PI/16) * cos((2*j+1)*v*PI/16)); int prevDC[3] = {0, 0, 0}; for(int y = 0; y < m_h; y += 8) { int jj = min(m_h - y, 8); for(int x = 0; x < m_w; x += 8) { int ii = min(m_w - x, 8); for(int c = 0; c < ColorComponents; c++) { int cc = !!c; int ACs = 0; static short block[64]; for(int zigzag = 0; zigzag < 64; zigzag++) { BYTE u = zigzagU[zigzag]; BYTE v = zigzagV[zigzag]; float F = 0; /* for(int j = 0; j < jj; j++) for(int i = 0; i < ii; i++) F += (signed char)m_p[((y+j)*m_w + (x+i))*4 + c] * cosuv[v][u][j][i]; */ for(int j = 0; j < jj; j++) { signed char* p = (signed char*)&m_p[((y+j)*m_w + x)*4 + c]; for(int i = 0; i < ii; i++, p += 4) F += *p * cosuv[v][u][j][i]; } float cu = !u ? invsq2 : 1.0f; float cv = !v ? invsq2 : 1.0f; block[zigzag] = short(2.0 / 8.0 * cu * cv * F) / quanttbl[cc][zigzag]; } short DC = block[0] - prevDC[c]; prevDC[c] = block[0]; int size = GetBitWidth(DC); PutBit(DCVLC[cc][size], DCVLC_Size[cc][size]); if(DC < 0) DC = DC - 1; PutBit(DC, size); int j; for(j = 64; j > 1 && !block[j-1]; j--); for(int i = 1; i < j; i++) { short AC = block[i]; if(AC == 0) { if(++ACs == 16) { PutBit(ACVLC[cc][15][0], ACVLC_Size[cc][15][0]); ACs = 0; } } else { int size = GetBitWidth(AC); PutBit(ACVLC[cc][ACs][size], ACVLC_Size[cc][ACs][size]); if(AC < 0) AC--; PutBit(AC, size); ACs = 0; } } if(j < 64) PutBit(ACVLC[cc][0][0], ACVLC_Size[cc][0][0]); } } } Flush(); }
// ѹËõ int CYTCompress::Compress(char * inbuf, unsigned short inlen, char * outbuf, unsigned short outlen) { if(inlen > 8192) { return -1; } unsigned char * buf = (unsigned char *)inbuf; Init(); memset(outbuf, 0, outlen); unsigned short limitsize = min(outlen, inlen); int errorcode; int inputptr = 1; int charecter; unsigned int index; int nextcode = 258; unsigned int outbitptr = 0; unsigned int outbitsize = 9; int nextbumpsize = 512; int stringcode = (int)buf[0]; while(inputptr < inlen) { charecter = (int)buf[inputptr]; index = FindChildNode(stringcode, charecter); if(index == (unsigned int)(-1)) { return -1; } if(m_dictory[index].codevalue != -1) { stringcode = (int)m_dictory[index].codevalue; } else { m_dictory[index].codevalue = (short)nextcode; m_dictory[index].parentcode = (short)stringcode; m_dictory[index].character = (char)charecter; if((errorcode = PutBit(outbuf, limitsize, outbitptr, stringcode, outbitsize)) < 0) { return errorcode; } nextcode++; stringcode = charecter; outbitptr += outbitsize; if(nextcode >= nextbumpsize) { if((errorcode = PutBit(outbuf, limitsize, outbitptr, (unsigned int)257, outbitsize)) < 0) { return errorcode; } outbitptr += outbitsize; outbitsize++; nextbumpsize = nextbumpsize << 1; } } inputptr++; } if((errorcode = PutBit(outbuf, limitsize, outbitptr, stringcode, outbitsize)) < 0) { return errorcode; } if((errorcode = PutBit(outbuf, limitsize, outbitptr+outbitsize, 256, outbitsize)) < 0) { return errorcode; } outbitptr += outbitsize + outbitsize; int retsize = 0; if((outbitptr % 8) != 0) { retsize = (outbitptr >> 3) + 1; }
static int WriteICSInfo(CoderInfo *coderInfo, BitStream *bitStream, int objectType, int common_window, int writeFlag) { int grouping_bits; int bits = 0; if (writeFlag) { /* write out ics_info() information */ PutBit(bitStream, 0, LEN_ICS_RESERV); /* reserved Bit*/ /* Write out window sequence */ PutBit(bitStream, coderInfo->block_type, LEN_WIN_SEQ); /* block type */ /* Write out window shape */ PutBit(bitStream, coderInfo->window_shape, LEN_WIN_SH); /* window shape */ } bits += LEN_ICS_RESERV; bits += LEN_WIN_SEQ; bits += LEN_WIN_SH; /* For short windows, write out max_sfb and scale_factor_grouping */ if (coderInfo->block_type == ONLY_SHORT_WINDOW){ if (writeFlag) { PutBit(bitStream, coderInfo->max_sfb, LEN_MAX_SFBS); grouping_bits = FindGroupingBits(coderInfo); PutBit(bitStream, grouping_bits, MAX_SHORT_WINDOWS - 1); /* the grouping bits */ } bits += LEN_MAX_SFBS; bits += MAX_SHORT_WINDOWS - 1; } else { /* Otherwise, write out max_sfb and predictor data */ if (writeFlag) { PutBit(bitStream, coderInfo->max_sfb, LEN_MAX_SFBL); } bits += LEN_MAX_SFBL; #ifdef DRM } if (writeFlag) { PutBit(bitStream,coderInfo->tnsInfo.tnsDataPresent,LEN_TNS_PRES); } bits += LEN_TNS_PRES; #endif if (objectType == LTP) { bits++; if(writeFlag) PutBit(bitStream, coderInfo->ltpInfo.global_pred_flag, 1); /* Prediction Global used */ bits += WriteLTPPredictorData(coderInfo, bitStream, writeFlag); if (common_window) bits += WriteLTPPredictorData(coderInfo, bitStream, writeFlag); } else { bits++; if (writeFlag) PutBit(bitStream, coderInfo->pred_global_flag, LEN_PRED_PRES); /* predictor_data_present */ bits += WritePredictorData(coderInfo, bitStream, writeFlag); } #ifndef DRM }
static int WriteADTSHeader(faacEncHandle hEncoder, BitStream *bitStream, int writeFlag) { int bits = 56; if (writeFlag) { /* Fixed ADTS header */ PutBit(bitStream, 0xFFFF, 12); /* 12 bit Syncword */ PutBit(bitStream, hEncoder->config.mpegVersion, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */ PutBit(bitStream, 0, 2); /* layer == 0 */ PutBit(bitStream, 1, 1); /* protection absent */ PutBit(bitStream, hEncoder->config.aacObjectType - 1, 2); /* profile */ PutBit(bitStream, hEncoder->sampleRateIdx, 4); /* sampling rate */ PutBit(bitStream, 0, 1); /* private bit */ PutBit(bitStream, hEncoder->numChannels, 3); /* ch. config (must be > 0) */ /* simply using numChannels only works for 6 channels or less, else a channel configuration should be written */ PutBit(bitStream, 0, 1); /* original/copy */ PutBit(bitStream, 0, 1); /* home */ #if 0 // Removed in corrigendum 14496-3:2002 if (hEncoder->config.mpegVersion == 0) PutBit(bitStream, 0, 2); /* emphasis */ #endif /* Variable ADTS header */ PutBit(bitStream, 0, 1); /* copyr. id. bit */ PutBit(bitStream, 0, 1); /* copyr. id. start */ PutBit(bitStream, hEncoder->usedBytes, 13); PutBit(bitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */ PutBit(bitStream, 0, 2); /* raw data blocks (0+1=1) */ } /* * MPEG2 says byte_aligment() here, but ADTS always is multiple of 8 bits * MPEG4 has no byte_alignment() here */ /* if (hEncoder->config.mpegVersion == 1) bits += ByteAlign(bitStream, writeFlag); */ #if 0 // Removed in corrigendum 14496-3:2002 if (hEncoder->config.mpegVersion == 0) bits += 2; /* emphasis */ #endif return bits; }
int WriteBitstream(faacEncHandle hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannel) { int channel; int bits = 0; int bitsLeftAfterFill, numFillBits; CountBitstream(hEncoder, coderInfo, channelInfo, bitStream, numChannel); if(hEncoder->config.outputFormat == 1){ bits += WriteADTSHeader(hEncoder, bitStream, 1); }else{ bits = 0; // compilier will remove it, byt anyone will see that current size of bitstream is 0 } /* sur: faad2 complains about scalefactor error if we are writing FAAC String */ #ifndef DRM if (hEncoder->frameNum == 4) WriteFAACStr(bitStream, hEncoder->config.name, 1); #endif for (channel = 0; channel < numChannel; channel++) { if (channelInfo[channel].present) { /* Write out a single_channel_element */ if (!channelInfo[channel].cpe) { if (channelInfo[channel].lfe) { /* Write out lfe */ bits += WriteLFE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } else { /* Write out sce */ bits += WriteSCE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } } else { if (channelInfo[channel].ch_is_left) { /* Write out cpe */ bits += WriteCPE(&coderInfo[channel], &coderInfo[channelInfo[channel].paired_ch], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } } } } /* Compute how many fill bits are needed to avoid overflowing bit reservoir */ /* Save room for ID_END terminator */ if (bits < (8 - LEN_SE_ID) ) { numFillBits = 8 - LEN_SE_ID - bits; } else { numFillBits = 0; } /* Write AAC fill_elements, smallest fill element is 7 bits. */ /* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */ numFillBits += 6; bitsLeftAfterFill = WriteAACFillBits(bitStream, numFillBits, 1); bits += (numFillBits - bitsLeftAfterFill); /* Write ID_END terminator */ bits += LEN_SE_ID; PutBit(bitStream, ID_END, LEN_SE_ID); /* Now byte align the bitstream */ /* * This byte_alignment() is correct for both MPEG2 and MPEG4, although * in MPEG4 the byte_alignment() is officially done before the new frame * instead of at the end. But this is basically the same. */ bits += ByteAlign(bitStream, 1, bits); return bits; }