├── .gitattributes ├── 00001.yuv ├── 2.jpg ├── README.md ├── cscope.out ├── test.c ├── test.out ├── yuv2jpg ├── yuv2jpg.c └── yuv2jpg.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /00001.yuv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quinncy/yuv420p_jpg_linux_C/6c17ce072fba624f65aaa13e713d0d8b58e52361/00001.yuv -------------------------------------------------------------------------------- /2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quinncy/yuv420p_jpg_linux_C/6c17ce072fba624f65aaa13e713d0d8b58e52361/2.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yuv420p_jpg_linux_C 2 | -------------------------------------------------------------------------------- /cscope.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quinncy/yuv420p_jpg_linux_C/6c17ce072fba624f65aaa13e713d0d8b58e52361/cscope.out -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "yuv2jpg.h" 7 | 8 | int get_Y_U_V(unsigned char*rData,unsigned char* in_Y,unsigned char* in_U,unsigned char* in_V,int nStride,int height) 9 | { 10 | int i = 0; 11 | int y_n =0; 12 | int u_n =0; 13 | int v_n =0; 14 | int u = 0; 15 | int v = 2; 16 | long size = nStride*height*3/2; 17 | //yuv422格式读取 18 | #if 0 19 | while(i 3 | #include 4 | 5 | void ProcessUV(unsigned char* pUVBuf,unsigned char* pTmpUVBuf,int width,int height,int nStride) 6 | { 7 | //原来程序 8 | #if 0 9 | int i=0; 10 | while(i 100) quality = 100; 35 | if (quality < 50) 36 | quality = 5000 / quality; 37 | else 38 | quality = 200 - quality*2; 39 | 40 | return quality; 41 | } 42 | 43 | void DivBuff(unsigned char* pBuf,int width,int height,int nStride,int xLen,int yLen) 44 | { 45 | int xBufs = width/xLen; 46 | int yBufs= height/yLen; 47 | int tmpBufLen = xBufs * xLen * yLen; 48 | unsigned char* tmpBuf = (unsigned char*)malloc(tmpBufLen); 49 | int i; 50 | int j; 51 | int k; 52 | int n; 53 | int bufOffset = 0; 54 | for (i = 0; i < yBufs; ++i) 55 | { 56 | n = 0; 57 | for (j = 0; j < xBufs; ++j) 58 | { 59 | bufOffset = yLen * i * nStride + j * xLen; 60 | for (k = 0; k < yLen; ++k) 61 | { 62 | memcpy(tmpBuf + n,pBuf +bufOffset,xLen); 63 | n += xLen; 64 | bufOffset += nStride; 65 | } 66 | } 67 | memcpy(pBuf +i * tmpBufLen,tmpBuf,tmpBufLen); 68 | } 69 | free(tmpBuf); 70 | } 71 | 72 | void SetQuantTable(unsigned char* std_QT,unsigned char* QT, int Q) 73 | { 74 | int tmpVal = 0; 75 | int i; 76 | for (i = 0; i < DCTBLOCKSIZE; ++i) 77 | { 78 | tmpVal = (std_QT[i] * Q + 50L) / 100L; 79 | 80 | if (tmpVal < 1) 81 | { 82 | tmpVal = 1L; 83 | } 84 | if (tmpVal > 255) 85 | { 86 | tmpVal = 255L; 87 | } 88 | QT[FZBT[i]] = (unsigned char)tmpVal; 89 | } 90 | } 91 | 92 | void InitQTForAANDCT(JPEGINFO *pJpgInfo) 93 | { 94 | unsigned int i = 0; 95 | unsigned int j = 0; 96 | unsigned int k = 0; 97 | 98 | for (i = 0; i < DCTSIZE; i++) 99 | { 100 | for (j = 0; j < DCTSIZE; j++) 101 | { 102 | pJpgInfo->YQT_DCT[k] = (float) (1.0 / ((double) pJpgInfo->YQT[FZBT[k]] * 103 | aanScaleFactor[i] * aanScaleFactor[j] * 8.0)); 104 | ++k; 105 | } 106 | } 107 | 108 | k = 0; 109 | for (i = 0; i < DCTSIZE; i++) 110 | { 111 | for (j = 0; j < DCTSIZE; j++) 112 | { 113 | pJpgInfo->UVQT_DCT[k] = (float) (1.0 / ((double) pJpgInfo->UVQT[FZBT[k]] * 114 | aanScaleFactor[i] * aanScaleFactor[j] * 8.0)); 115 | ++k; 116 | } 117 | } 118 | } 119 | 120 | unsigned char ComputeVLI(short val) 121 | { 122 | unsigned char binStrLen = 0; 123 | val = fabs(val); 124 | 125 | if(val == 1) 126 | { 127 | binStrLen = 1; 128 | } 129 | else if(val >= 2 && val <= 3) 130 | { 131 | binStrLen = 2; 132 | } 133 | else if(val >= 4 && val <= 7) 134 | { 135 | binStrLen = 3; 136 | } 137 | else if(val >= 8 && val <= 15) 138 | { 139 | binStrLen = 4; 140 | } 141 | else if(val >= 16 && val <= 31) 142 | { 143 | binStrLen = 5; 144 | } 145 | else if(val >= 32 && val <= 63) 146 | { 147 | binStrLen = 6; 148 | } 149 | else if(val >= 64 && val <= 127) 150 | { 151 | binStrLen = 7; 152 | } 153 | else if(val >= 128 && val <= 255) 154 | { 155 | binStrLen = 8; 156 | } 157 | else if(val >= 256 && val <= 511) 158 | { 159 | binStrLen = 9; 160 | } 161 | else if(val >= 512 && val <= 1023) 162 | { 163 | binStrLen = 10; 164 | } 165 | else if(val >= 1024 && val <= 2047) 166 | { 167 | binStrLen = 11; 168 | } 169 | 170 | return binStrLen; 171 | } 172 | 173 | void BuildVLITable(JPEGINFO *pJpgInfo) 174 | { 175 | short i = 0; 176 | 177 | for (i = 0; i < DC_MAX_QUANTED; ++i) 178 | { 179 | pJpgInfo->pVLITAB[i] = ComputeVLI(i); 180 | } 181 | 182 | for (i = DC_MIN_QUANTED; i < 0; ++i) 183 | { 184 | pJpgInfo->pVLITAB[i] = ComputeVLI(i); 185 | } 186 | } 187 | 188 | int WriteSOI(unsigned char* pOut,int nDataLen) 189 | { 190 | memcpy(pOut+nDataLen,&SOITAG,sizeof(SOITAG)); 191 | return nDataLen+sizeof(SOITAG); 192 | } 193 | 194 | 195 | int WriteEOI(unsigned char* pOut,int nDataLen) 196 | { 197 | memcpy(pOut+nDataLen,&EOITAG,sizeof(EOITAG)); 198 | return nDataLen + sizeof(EOITAG); 199 | } 200 | 201 | 202 | int WriteAPP0(unsigned char* pOut,int nDataLen) 203 | { 204 | JPEGAPP0 APP0; 205 | APP0.segmentTag = 0xE0FF; 206 | APP0.length = 0x1000; 207 | APP0.id[0] = 'J'; 208 | APP0.id[1] = 'F'; 209 | APP0.id[2] = 'I'; 210 | APP0.id[3] = 'F'; 211 | APP0.id[4] = 0; 212 | APP0.ver = 0x0101; 213 | APP0.densityUnit = 0x00; 214 | APP0.densityX = 0x0100; 215 | APP0.densityY = 0x0100; 216 | APP0.thp = 0x00; 217 | APP0.tvp = 0x00; 218 | //memcpy(pOut+nDataLen,&APP0,sizeof(APP0)); 219 | memcpy(pOut+nDataLen,&APP0.segmentTag,2); 220 | memcpy(pOut+nDataLen+2,&APP0.length,2); 221 | memcpy(pOut+nDataLen+4,APP0.id,5); 222 | memcpy(pOut+nDataLen+9,&APP0.ver,2); 223 | *(pOut+nDataLen+11) = APP0.densityUnit; 224 | memcpy(pOut+nDataLen+12,&APP0.densityX,2); 225 | memcpy(pOut+nDataLen+14,&APP0.densityY,2); 226 | *(pOut+nDataLen+16) = APP0.thp; 227 | *(pOut+nDataLen+17) = APP0.tvp; 228 | 229 | return nDataLen + sizeof(APP0)-2; 230 | 231 | } 232 | 233 | 234 | int WriteDQT(JPEGINFO *pJpgInfo,unsigned char* pOut,int nDataLen) 235 | { 236 | 237 | unsigned int i = 0; 238 | JPEGDQT_8BITS DQT_Y; 239 | DQT_Y.segmentTag = 0xDBFF; 240 | DQT_Y.length = 0x4300; 241 | DQT_Y.tableInfo = 0x00; 242 | for (i = 0; i < DCTBLOCKSIZE; i++) 243 | { 244 | DQT_Y.table[i] = pJpgInfo->YQT[i]; 245 | } 246 | //memcpy(pOut+nDataLen , &DQT_Y,sizeof(DQT_Y)); 247 | memcpy(pOut+nDataLen,&DQT_Y.segmentTag,2); 248 | memcpy(pOut+nDataLen+2,&DQT_Y.length,2); 249 | *(pOut+nDataLen+4) = DQT_Y.tableInfo; 250 | memcpy(pOut+nDataLen+5,DQT_Y.table,64); 251 | 252 | nDataLen += sizeof(DQT_Y)-1; 253 | DQT_Y.tableInfo = 0x01; 254 | for (i = 0; i < DCTBLOCKSIZE; i++) 255 | { 256 | DQT_Y.table[i] = pJpgInfo->UVQT[i]; 257 | } 258 | //memcpy(pOut+nDataLen,&DQT_Y,sizeof(DQT_Y)); 259 | memcpy(pOut+nDataLen,&DQT_Y.segmentTag,2); 260 | memcpy(pOut+nDataLen+2,&DQT_Y.length,2); 261 | *(pOut+nDataLen+4) = DQT_Y.tableInfo; 262 | memcpy(pOut+nDataLen+5,DQT_Y.table,64); 263 | nDataLen += sizeof(DQT_Y)-1; 264 | return nDataLen; 265 | } 266 | 267 | 268 | 269 | unsigned short Intel2Moto(unsigned short val) 270 | { 271 | unsigned char highBits = (unsigned char)(val / 256); 272 | unsigned char lowBits = (unsigned char)(val % 256); 273 | return lowBits * 256 + highBits; 274 | } 275 | 276 | 277 | int WriteSOF(unsigned char* pOut,int nDataLen,int width,int height) 278 | { 279 | JPEGSOF0_24BITS SOF; 280 | SOF.segmentTag = 0xC0FF; 281 | SOF.length = 0x1100; 282 | SOF.precision = 0x08; 283 | SOF.height = Intel2Moto((unsigned short)height); 284 | SOF.width = Intel2Moto((unsigned short)width); 285 | SOF.sigNum = 0x03; 286 | SOF.YID = 0x01; 287 | SOF.QTY = 0x00; 288 | SOF.UID = 0x02; 289 | SOF.QTU = 0x01; 290 | SOF.VID = 0x03; 291 | SOF.QTV = 0x01; 292 | SOF.HVU = 0x11; 293 | SOF.HVV = 0x11; 294 | SOF.HVY = 0x11; 295 | // memcpy(pOut + nDataLen,&SOF,sizeof(SOF)); 296 | memcpy(pOut+nDataLen,&SOF.segmentTag,2); 297 | memcpy(pOut+nDataLen+2,&SOF.length,2); 298 | *(pOut+nDataLen+4) = SOF.precision; 299 | memcpy(pOut+nDataLen+5,&SOF.height,2); 300 | memcpy(pOut+nDataLen+7,&SOF.width,2); 301 | *(pOut+nDataLen+9) = SOF.sigNum; 302 | *(pOut+nDataLen+10) = SOF.YID; 303 | *(pOut+nDataLen+11) = SOF.HVY; 304 | *(pOut+nDataLen+12) = SOF.QTY; 305 | *(pOut+nDataLen+13) = SOF.UID; 306 | *(pOut+nDataLen+14) = SOF.HVU; 307 | *(pOut+nDataLen+15) = SOF.QTU; 308 | *(pOut+nDataLen+16) = SOF.VID; 309 | *(pOut+nDataLen+17) = SOF.HVV; 310 | *(pOut+nDataLen+18) = SOF.QTV; 311 | return nDataLen + sizeof(SOF)-1; 312 | } 313 | 314 | 315 | int WriteByte(unsigned char val,unsigned char* pOut,int nDataLen) 316 | { 317 | pOut[nDataLen] = val; 318 | return nDataLen + 1; 319 | } 320 | 321 | int WriteDHT(unsigned char* pOut,int nDataLen) 322 | { 323 | unsigned int i = 0; 324 | 325 | JPEGDHT DHT; 326 | DHT.segmentTag = 0xC4FF; 327 | DHT.length = Intel2Moto(19 + 12); 328 | DHT.tableInfo = 0x00; 329 | for (i = 0; i < 16; i++) 330 | { 331 | DHT.huffCode[i] = STD_DC_Y_NRCODES[i + 1]; 332 | } 333 | //memcpy(pOut+nDataLen,&DHT,sizeof(DHT)); 334 | memcpy(pOut+nDataLen,&DHT.segmentTag,2); 335 | memcpy(pOut+nDataLen+2,&DHT.length,2); 336 | *(pOut+nDataLen+4) = DHT.tableInfo; 337 | memcpy(pOut+nDataLen+5,DHT.huffCode,16); 338 | nDataLen += sizeof(DHT)-1; 339 | for (i = 0; i <= 11; i++) 340 | { 341 | nDataLen = WriteByte(STD_DC_Y_VALUES[i],pOut,nDataLen); 342 | } 343 | DHT.tableInfo = 0x01; 344 | for (i = 0; i < 16; i++) 345 | { 346 | DHT.huffCode[i] = STD_DC_UV_NRCODES[i + 1]; 347 | } 348 | //memcpy(pOut+nDataLen,&DHT,sizeof(DHT)); 349 | memcpy(pOut+nDataLen,&DHT.segmentTag,2); 350 | memcpy(pOut+nDataLen+2,&DHT.length,2); 351 | *(pOut+nDataLen+4) = DHT.tableInfo; 352 | memcpy(pOut+nDataLen+5,DHT.huffCode,16); 353 | nDataLen += sizeof(DHT)-1; 354 | for (i = 0; i <= 11; i++) 355 | { 356 | nDataLen = WriteByte(STD_DC_UV_VALUES[i],pOut,nDataLen); 357 | } 358 | DHT.length = Intel2Moto(19 + 162); 359 | DHT.tableInfo = 0x10; 360 | for (i = 0; i < 16; i++) 361 | { 362 | DHT.huffCode[i] = STD_AC_Y_NRCODES[i + 1]; 363 | } 364 | //memcpy(pOut+nDataLen,&DHT,sizeof(DHT)); 365 | memcpy(pOut+nDataLen,&DHT.segmentTag,2); 366 | memcpy(pOut+nDataLen+2,&DHT.length,2); 367 | *(pOut+nDataLen+4) = DHT.tableInfo; 368 | memcpy(pOut+nDataLen+5,DHT.huffCode,16); 369 | nDataLen += sizeof(DHT)-1; 370 | for (i = 0; i <= 161; i++) 371 | { 372 | nDataLen = WriteByte(STD_AC_Y_VALUES[i],pOut,nDataLen); 373 | } 374 | DHT.tableInfo = 0x11; 375 | for (i = 0; i < 16; i++) 376 | { 377 | DHT.huffCode[i] = STD_AC_UV_NRCODES[i + 1]; 378 | } 379 | //memcpy(pOut + nDataLen,&DHT,sizeof(DHT)); 380 | memcpy(pOut+nDataLen,&DHT.segmentTag,2); 381 | memcpy(pOut+nDataLen+2,&DHT.length,2); 382 | *(pOut+nDataLen+4) = DHT.tableInfo; 383 | memcpy(pOut+nDataLen+5,DHT.huffCode,16); 384 | nDataLen += sizeof(DHT)-1; 385 | for (i = 0; i <= 161; i++) 386 | { 387 | nDataLen = WriteByte(STD_AC_UV_VALUES[i],pOut,nDataLen); 388 | } 389 | return nDataLen; 390 | } 391 | 392 | 393 | int WriteSOS(unsigned char* pOut,int nDataLen) 394 | { 395 | JPEGSOS_24BITS SOS; 396 | SOS.segmentTag = 0xDAFF; 397 | SOS.length = 0x0C00; 398 | SOS.sigNum = 0x03; 399 | SOS.YID = 0x01; 400 | SOS.HTY = 0x00; 401 | SOS.UID = 0x02; 402 | SOS.HTU = 0x11; 403 | SOS.VID = 0x03; 404 | SOS.HTV = 0x11; 405 | SOS.Se = 0x3F; 406 | SOS.Ss = 0x00; 407 | SOS.Bf = 0x00; 408 | memcpy(pOut+nDataLen,&SOS,sizeof(SOS)); 409 | return nDataLen+sizeof(SOS); 410 | } 411 | 412 | 413 | void BuildSTDHuffTab(unsigned char* nrcodes,unsigned char* stdTab,HUFFCODE* huffCode) 414 | { 415 | unsigned char i = 0; 416 | unsigned char j = 0; 417 | unsigned char k = 0; 418 | unsigned short code = 0; 419 | 420 | for (i = 1; i <= 16; i++) 421 | { 422 | for (j = 1; j <= nrcodes[i]; j++) 423 | { 424 | huffCode[stdTab[k]].code = code; 425 | huffCode[stdTab[k]].length = i; 426 | ++k; 427 | ++code; 428 | } 429 | code*=2; 430 | } 431 | 432 | for (i = 0; i < k; i++) 433 | { 434 | huffCode[i].val = stdTab[i]; 435 | } 436 | } 437 | 438 | void FDCT(float* lpBuff) 439 | { 440 | float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; 441 | float tmp10, tmp11, tmp12, tmp13; 442 | float z1, z2, z3, z4, z5, z11, z13; 443 | float* dataptr; 444 | int ctr; 445 | 446 | 447 | dataptr = lpBuff; 448 | for (ctr = DCTSIZE-1; ctr >= 0; ctr--) 449 | { 450 | tmp0 = dataptr[0] + dataptr[7]; 451 | tmp7 = dataptr[0] - dataptr[7]; 452 | tmp1 = dataptr[1] + dataptr[6]; 453 | tmp6 = dataptr[1] - dataptr[6]; 454 | tmp2 = dataptr[2] + dataptr[5]; 455 | tmp5 = dataptr[2] - dataptr[5]; 456 | tmp3 = dataptr[3] + dataptr[4]; 457 | tmp4 = dataptr[3] - dataptr[4]; 458 | 459 | 460 | tmp10 = tmp0 + tmp3; 461 | tmp13 = tmp0 - tmp3; 462 | tmp11 = tmp1 + tmp2; 463 | tmp12 = tmp1 - tmp2; 464 | 465 | dataptr[0] = tmp10 + tmp11; /* phase 3 */ 466 | dataptr[4] = tmp10 - tmp11; 467 | 468 | z1 = (float)((tmp12 + tmp13) * (0.707106781)); /* c4 */ 469 | dataptr[2] = tmp13 + z1; /* phase 5 */ 470 | dataptr[6] = tmp13 - z1; 471 | 472 | 473 | tmp10 = tmp4 + tmp5; /* phase 2 */ 474 | tmp11 = tmp5 + tmp6; 475 | tmp12 = tmp6 + tmp7; 476 | 477 | z5 = (float)((tmp10 - tmp12) * ( 0.382683433)); /* c6 */ 478 | z2 = (float)((0.541196100) * tmp10 + z5); /* c2-c6 */ 479 | z4 = (float)((1.306562965) * tmp12 + z5); /* c2+c6 */ 480 | z3 = (float)(tmp11 * (0.707106781)); /* c4 */ 481 | 482 | z11 = tmp7 + z3; 483 | z13 = tmp7 - z3; 484 | 485 | dataptr[5] = z13 + z2; /* phase 6 */ 486 | dataptr[3] = z13 - z2; 487 | dataptr[1] = z11 + z4; 488 | dataptr[7] = z11 - z4; 489 | 490 | dataptr += DCTSIZE; 491 | } 492 | 493 | dataptr = lpBuff; 494 | for (ctr = DCTSIZE-1; ctr >= 0; ctr--) 495 | { 496 | tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; 497 | tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; 498 | tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; 499 | tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; 500 | tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; 501 | tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; 502 | tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; 503 | tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; 504 | 505 | 506 | tmp10 = tmp0 + tmp3; 507 | tmp13 = tmp0 - tmp3; 508 | tmp11 = tmp1 + tmp2; 509 | tmp12 = tmp1 - tmp2; 510 | 511 | dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ 512 | dataptr[DCTSIZE*4] = tmp10 - tmp11; 513 | 514 | z1 = (float)((tmp12 + tmp13) * (0.707106781)); /* c4 */ 515 | dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ 516 | dataptr[DCTSIZE*6] = tmp13 - z1; 517 | 518 | tmp10 = tmp4 + tmp5; /* phase 2 */ 519 | tmp11 = tmp5 + tmp6; 520 | tmp12 = tmp6 + tmp7; 521 | 522 | z5 = (float)((tmp10 - tmp12) * (0.382683433)); /* c6 */ 523 | z2 = (float)((0.541196100) * tmp10 + z5); /* c2-c6 */ 524 | z4 = (float)((1.306562965) * tmp12 + z5); /* c2+c6 */ 525 | z3 = (float)(tmp11 * (0.707106781)); /* c4 */ 526 | 527 | z11 = tmp7 + z3; /* phase 5 */ 528 | z13 = tmp7 - z3; 529 | 530 | dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ 531 | dataptr[DCTSIZE*3] = z13 - z2; 532 | dataptr[DCTSIZE*1] = z11 + z4; 533 | dataptr[DCTSIZE*7] = z11 - z4; 534 | 535 | ++dataptr; 536 | } 537 | } 538 | 539 | 540 | int WriteBitsStream(JPEGINFO *pJpgInfo,unsigned short value,unsigned char codeLen,unsigned char* pOut,int nDataLen) 541 | { 542 | char posval;//bit position in the bitstring we read, should be<=15 and >=0 543 | posval=codeLen-1; 544 | printf("posval is %d\n",posval); 545 | while (posval>=0) 546 | { 547 | if (value & mask[posval]) 548 | { 549 | pJpgInfo->bytenew|=mask[pJpgInfo->bytepos]; 550 | } 551 | posval--; 552 | pJpgInfo->bytepos--; 553 | if (pJpgInfo->bytepos<0) 554 | { 555 | if (pJpgInfo->bytenew==0xFF) 556 | { 557 | nDataLen = WriteByte(0xFF,pOut,nDataLen); 558 | nDataLen = WriteByte(0,pOut,nDataLen); 559 | } 560 | else 561 | { 562 | nDataLen = WriteByte(pJpgInfo->bytenew,pOut,nDataLen); 563 | } 564 | pJpgInfo->bytepos=7; 565 | pJpgInfo->bytenew=0; 566 | } 567 | } 568 | return nDataLen; 569 | } 570 | 571 | int WriteBits(JPEGINFO *pJpgInfo,HUFFCODE huffCode,unsigned char* pOut,int nDataLen) 572 | { 573 | return WriteBitsStream(pJpgInfo,huffCode.code,huffCode.length,pOut,nDataLen); 574 | } 575 | 576 | int WriteBits2(JPEGINFO *pJpgInfo,SYM2 sym,unsigned char* pOut,int nDataLen) 577 | { 578 | return WriteBitsStream(pJpgInfo,sym.amplitude,sym.codeLen,pOut,nDataLen); 579 | } 580 | 581 | double mypow(double x,double y){ 582 | int i=0; 583 | double sum=1; 584 | for(i=1;i<=(int)y;i++) 585 | sum *=x; 586 | return sum; 587 | } 588 | 589 | SYM2 BuildSym2(short value) 590 | { 591 | SYM2 Symbol; 592 | 593 | Symbol.codeLen = ComputeVLI(value); 594 | Symbol.amplitude = 0; 595 | if (value >= 0) 596 | { 597 | Symbol.amplitude = value; 598 | } 599 | else 600 | { 601 | double tmp = mypow(2,Symbol.codeLen); 602 | Symbol.amplitude = (short)(tmp-1) + value; 603 | } 604 | 605 | return Symbol; 606 | } 607 | 608 | 609 | void RLEComp(short* lpbuf,ACSYM* lpOutBuf,unsigned char *resultLen) 610 | { 611 | unsigned char zeroNum = 0; 612 | unsigned int EOBPos = 0; 613 | unsigned char MAXZEROLEN = 15; 614 | unsigned int i = 0; 615 | unsigned int j = 0; 616 | 617 | EOBPos = DCTBLOCKSIZE - 1; 618 | for (i = EOBPos; i > 0; i--) 619 | { 620 | if (lpbuf[i] == 0) 621 | { 622 | --EOBPos; 623 | } 624 | else 625 | { 626 | break; 627 | } 628 | } 629 | 630 | for (i = 1; i <= EOBPos; i++) 631 | { 632 | if (lpbuf[i] == 0 && zeroNum < MAXZEROLEN) 633 | { 634 | ++zeroNum; 635 | } 636 | else 637 | { 638 | lpOutBuf[j].zeroLen = zeroNum; 639 | lpOutBuf[j].codeLen = ComputeVLI(lpbuf[i]); 640 | lpOutBuf[j].amplitude = lpbuf[i]; 641 | zeroNum = 0; 642 | ++(*resultLen); 643 | ++j; 644 | } 645 | } 646 | } 647 | 648 | 649 | int ProcessDU(JPEGINFO *pJpgInfo,float* lpBuf,float* quantTab,HUFFCODE* dcHuffTab,HUFFCODE* acHuffTab,short* DC,unsigned char* pOut,int nDataLen) 650 | { 651 | unsigned char i = 0; 652 | unsigned int j = 0; 653 | short diffVal = 0; 654 | unsigned char acLen = 0; 655 | short sigBuf[DCTBLOCKSIZE]; 656 | ACSYM acSym[DCTBLOCKSIZE]; 657 | FDCT(lpBuf); 658 | 659 | for (i = 0; i < DCTBLOCKSIZE; i++) 660 | { 661 | sigBuf[FZBT[i]] = (short)((lpBuf[i] * quantTab[i] + 16384.5) - 16384); 662 | } 663 | 664 | diffVal = sigBuf[0] - *DC; 665 | *DC = sigBuf[0]; 666 | 667 | if (diffVal == 0) 668 | { 669 | nDataLen = WriteBits(pJpgInfo,dcHuffTab[0],pOut,nDataLen); 670 | } 671 | else 672 | { 673 | nDataLen = WriteBits(pJpgInfo,dcHuffTab[pJpgInfo->pVLITAB[diffVal]],pOut,nDataLen); 674 | nDataLen = WriteBits2(pJpgInfo,BuildSym2(diffVal),pOut,nDataLen); 675 | } 676 | 677 | for (i = 63; (i > 0) && (sigBuf[i] == 0); i--) 678 | { 679 | 680 | } 681 | if (i == 0) 682 | { 683 | nDataLen = WriteBits(pJpgInfo,acHuffTab[0x00],pOut,nDataLen); 684 | } 685 | else 686 | { 687 | RLEComp(sigBuf,&acSym[0],&acLen); 688 | for (j = 0; j < acLen; j++) 689 | { 690 | if (acSym[j].codeLen == 0) 691 | { 692 | nDataLen = WriteBits(pJpgInfo,acHuffTab[0xF0],pOut,nDataLen); 693 | } 694 | else 695 | { 696 | nDataLen = WriteBits(pJpgInfo,acHuffTab[acSym[j].zeroLen * 16 + acSym[j].codeLen],pOut,nDataLen); 697 | nDataLen = WriteBits2(pJpgInfo,BuildSym2(acSym[j].amplitude),pOut,nDataLen); 698 | } 699 | } 700 | if (i != 63) 701 | { 702 | nDataLen = WriteBits(pJpgInfo,acHuffTab[0x00],pOut,nDataLen); 703 | } 704 | } 705 | 706 | return nDataLen; 707 | } 708 | 709 | 710 | int ProcessData(JPEGINFO *pJpgInfo,unsigned char* lpYBuf,unsigned char* lpUBuf,unsigned char* lpVBuf,int width,int height,int myBufLen, int muBufLen,int mvBufLen,unsigned char* pOut,int nDataLen) 711 | { 712 | size_t yBufLen = strlen(lpYBuf); 713 | size_t uBufLen = strlen(lpUBuf); 714 | size_t vBufLen = strlen(lpVBuf); 715 | float dctYBuf[DCTBLOCKSIZE]; 716 | float dctUBuf[DCTBLOCKSIZE]; 717 | float dctVBuf[DCTBLOCKSIZE]; 718 | unsigned int mcuNum = 0; 719 | short yDC = 0; 720 | short uDC = 0; 721 | short vDC = 0; 722 | unsigned char yCounter = 0; 723 | unsigned char uCounter = 0; 724 | unsigned char vCounter = 0; 725 | unsigned int i = 0; 726 | unsigned int j = 0; 727 | unsigned int k = 0; 728 | unsigned int p = 0; 729 | unsigned int m = 0; 730 | unsigned int n = 0; 731 | unsigned int s = 0; 732 | mcuNum = (height * width * 3)/(DCTBLOCKSIZE * 3); 733 | for (p = 0;p < mcuNum; p++) 734 | { 735 | yCounter = 1;//MCUIndex[SamplingType][0]; 736 | uCounter = 1;//MCUIndex[SamplingType][1]; 737 | vCounter = 1;//MCUIndex[SamplingType][2]; 738 | for (; i < yBufLen; i += DCTBLOCKSIZE) 739 | { 740 | for (j = 0; j < DCTBLOCKSIZE; j++) 741 | { 742 | dctYBuf[j] = (float)(lpYBuf[i + j] - 128); 743 | } 744 | if (yCounter > 0) 745 | { 746 | --yCounter; 747 | nDataLen = ProcessDU(pJpgInfo,dctYBuf,pJpgInfo->YQT_DCT,pJpgInfo->STD_DC_Y_HT,pJpgInfo->STD_AC_Y_HT,&yDC,pOut,nDataLen); 748 | } 749 | else 750 | { 751 | break; 752 | } 753 | } 754 | 755 | //------------------------------------------------------------------ 756 | for (; m < uBufLen; m += DCTBLOCKSIZE) 757 | { 758 | for (n = 0; n < DCTBLOCKSIZE; n++) 759 | { 760 | dctUBuf[n] = (float)(lpUBuf[m + n] - 128); 761 | } 762 | if (uCounter > 0) 763 | { 764 | --uCounter; 765 | nDataLen = ProcessDU(pJpgInfo,dctUBuf,pJpgInfo->UVQT_DCT,pJpgInfo->STD_DC_UV_HT,pJpgInfo->STD_AC_UV_HT,&uDC,pOut,nDataLen); 766 | } 767 | else 768 | { 769 | break; 770 | } 771 | } 772 | //------------------------------------------------------------------- 773 | for (; s < vBufLen; s += DCTBLOCKSIZE) 774 | { 775 | for (k = 0; k < DCTBLOCKSIZE; k++) 776 | { 777 | dctVBuf[k] = (float)(lpVBuf[s + k] - 128); 778 | } 779 | if (vCounter > 0) 780 | { 781 | --vCounter; 782 | nDataLen = ProcessDU(pJpgInfo,dctVBuf,pJpgInfo->UVQT_DCT,pJpgInfo->STD_DC_UV_HT,pJpgInfo->STD_AC_UV_HT,&vDC,pOut,nDataLen); 783 | } 784 | else 785 | { 786 | break; 787 | } 788 | } 789 | } 790 | return nDataLen; 791 | } 792 | 793 | int YUV2Jpg(unsigned char* in_Y,unsigned char* in_U,unsigned char* in_V,int width,int height,int quality,int nStride,unsigned char* pOut,unsigned long *pnOutSize) 794 | { 795 | unsigned char* pYBuf; 796 | unsigned char* pUBuf; 797 | unsigned char* pVBuf; 798 | int nYLen = nStride * height; 799 | //int nUVLen = nStride * height / 4; 800 | int nDataLen; 801 | JPEGINFO * JpgInfo; 802 | JpgInfo = (JPEGINFO *)malloc(sizeof(JPEGINFO)); 803 | 804 | printf("sizeof(JPEGAPP0)=\n"); 805 | printf("sizeof(JPEGDQT_8BITS)=\n"); 806 | printf("sizeof(JPEGSOF0_24BITS)=\n"); 807 | printf("sizeof(JPEGDHT)=%u\n",sizeof(JPEGDHT)); 808 | printf("10\n"); 809 | printf("sizeof(JPEGinfo)=%u\n",sizeof(JPEGINFO)); 810 | 811 | memset(JpgInfo,0,sizeof(JPEGINFO)); 812 | //printf("sizeof(JPEGINFO)=%d\n",sizeof(JPEGINFO)); 813 | //JpgInfo.bytenew = 0; 814 | //JpgInfo.bytepos = 7; 815 | JpgInfo->bytenew = 0; 816 | JpgInfo->bytepos = 7; 817 | printf("------------------------------6\n"); 818 | pYBuf = (unsigned char*)malloc(nYLen); 819 | memset(pYBuf,0,nYLen); 820 | //printf("nYLen=%d\n",nYLen); 821 | memcpy(pYBuf,in_Y,nYLen); 822 | printf("-----------------------------7\n"); 823 | pUBuf = (unsigned char*)malloc(nYLen); 824 | pVBuf = (unsigned char*)malloc(nYLen); 825 | printf("---------------------------------8\n"); 826 | //memcpy(pUBuf,in_U,nUVLen); 827 | //memcpy(pVBuf,in_V,nUVLen); 828 | //memset(pUBuf,0,nYLen/4); 829 | //memset(pVBuf,0,nYLen/4); 830 | 831 | ProcessUV(pUBuf,in_U,width,height,nStride); 832 | ProcessUV(pVBuf,in_V,width,height,nStride); 833 | printf("-------------------------------5\n"); 834 | DivBuff(pYBuf,width,height,nStride,DCTSIZE,DCTSIZE); 835 | DivBuff(pUBuf,width,height,nStride,DCTSIZE,DCTSIZE); 836 | DivBuff(pVBuf,width,height,nStride,DCTSIZE,DCTSIZE); 837 | quality = QualityScaling(quality); 838 | SetQuantTable(std_Y_QT,JpgInfo->YQT, quality); 839 | SetQuantTable(std_UV_QT,JpgInfo->UVQT,quality); 840 | 841 | InitQTForAANDCT(JpgInfo); 842 | JpgInfo->pVLITAB=JpgInfo->VLI_TAB +2048; 843 | BuildVLITable(JpgInfo); 844 | 845 | nDataLen = 0; 846 | printf("---------------------------2\n"); 847 | nDataLen = WriteSOI(pOut,nDataLen); 848 | nDataLen = WriteAPP0(pOut,nDataLen); 849 | nDataLen = WriteDQT(JpgInfo,pOut,nDataLen); 850 | nDataLen = WriteSOF(pOut,nDataLen,width,height); 851 | nDataLen = WriteDHT(pOut,nDataLen); 852 | nDataLen = WriteSOS(pOut,nDataLen); 853 | 854 | printf("------------------------------1\n"); 855 | BuildSTDHuffTab(STD_DC_Y_NRCODES,STD_DC_Y_VALUES,JpgInfo->STD_DC_Y_HT); 856 | BuildSTDHuffTab(STD_AC_Y_NRCODES,STD_AC_Y_VALUES,JpgInfo->STD_AC_Y_HT); 857 | BuildSTDHuffTab(STD_DC_UV_NRCODES,STD_DC_UV_VALUES,JpgInfo->STD_DC_UV_HT); 858 | BuildSTDHuffTab(STD_AC_UV_NRCODES,STD_AC_UV_VALUES,JpgInfo->STD_AC_UV_HT); 859 | printf("-----------------------------3\n"); 860 | nDataLen = ProcessData(JpgInfo,pYBuf,pUBuf,pVBuf,width,height,nYLen,nYLen,nYLen,pOut,nDataLen); 861 | nDataLen = WriteEOI(pOut,nDataLen); 862 | printf("------------------------------4\n"); 863 | free(JpgInfo); 864 | free(pYBuf); 865 | free(pUBuf); 866 | free(pVBuf); 867 | *pnOutSize = nDataLen; 868 | return 0; 869 | } 870 | -------------------------------------------------------------------------------- /yuv2jpg.h: -------------------------------------------------------------------------------- 1 | #ifndef _YUV2JPG_H__ 2 | #define _YUV2JPG_H__ 3 | #include 4 | #include 5 | 6 | #define DCTSIZE 8 7 | #define DCTBLOCKSIZE 64 8 | #define DC_MAX_QUANTED 2047 9 | #define DC_MIN_QUANTED -2048 10 | 11 | typedef struct tagHUFFCODE 12 | { 13 | unsigned short code; 14 | unsigned char length; 15 | unsigned short val; 16 | }HUFFCODE; 17 | 18 | typedef struct tagJPEGINFO 19 | { 20 | float YQT_DCT[DCTBLOCKSIZE]; 21 | float UVQT_DCT[DCTBLOCKSIZE]; 22 | unsigned char YQT[DCTBLOCKSIZE]; 23 | unsigned char UVQT[DCTBLOCKSIZE]; 24 | unsigned char VLI_TAB[4096]; 25 | unsigned char* pVLITAB; 26 | HUFFCODE STD_DC_Y_HT[12]; 27 | HUFFCODE STD_DC_UV_HT[12]; 28 | HUFFCODE STD_AC_Y_HT[256]; 29 | HUFFCODE STD_AC_UV_HT[256]; 30 | unsigned char bytenew; 31 | char bytepos; 32 | }JPEGINFO; 33 | 34 | static unsigned short SOITAG = 0xD8FF; 35 | static unsigned short EOITAG = 0xD9FF; 36 | 37 | static unsigned char FZBT[64]={ 38 | 0, 1, 5, 6, 14,15,27,28, 39 | 2, 4, 7, 13,16,26,29,42, 40 | 3, 8, 12,17,25,30,41,43, 41 | 9, 11,18,24,31,40,44,53, 42 | 10,19,23,32,39,45,52,54, 43 | 20,22,33,38,46,51,55,60, 44 | 21,34,37,47,50,56,59,61, 45 | 35,36,48,49,57,58,62,63 46 | }; 47 | 48 | static unsigned char std_Y_QT[64]={ 49 | 16, 11, 10, 16, 24, 40, 51, 61, 50 | 12, 12, 14, 19, 26, 58, 60, 55, 51 | 14, 13, 16, 24, 40, 57, 69, 56, 52 | 14, 17, 22, 29, 51, 87, 80, 62, 53 | 18, 22, 37, 56, 68, 109,103,77, 54 | 24, 35, 55, 64, 81, 104,113,92, 55 | 49, 64, 78, 87, 103,121,120,101, 56 | 72, 92, 95, 98, 112,100,103,99 57 | }; 58 | 59 | static unsigned char std_UV_QT[64]={ 60 | 17, 18, 24, 47, 99, 99, 99, 99, 61 | 18, 21, 26, 66, 99, 99, 99, 99, 62 | 24, 26, 56, 99, 99, 99, 99, 99, 63 | 47, 66, 99 ,99, 99, 99, 99, 99, 64 | 99, 99, 99, 99, 99, 99, 99, 99, 65 | 99, 99, 99, 99, 99, 99, 99, 99, 66 | 99, 99, 99, 99, 99, 99, 99, 99, 67 | 99, 99, 99, 99, 99, 99, 99, 99 68 | }; 69 | 70 | static double aanScaleFactor[8]={ 71 | 1.0, 1.387039845, 1.306562965, 1.175875602, 72 | 1.0, 0.785694958, 0.541196100, 0.275899379 73 | }; 74 | 75 | static unsigned char STD_DC_Y_NRCODES[17]={0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; 76 | 77 | static unsigned char STD_DC_Y_VALUES[12]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 78 | 79 | static unsigned char STD_DC_UV_NRCODES[17]={0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; 80 | 81 | static unsigned char STD_DC_UV_VALUES[12]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 82 | 83 | static unsigned char STD_AC_Y_NRCODES[17]={0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0X7D}; 84 | 85 | static unsigned char STD_AC_Y_VALUES[162]={ 86 | 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 87 | 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 88 | 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 89 | 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 90 | 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 91 | 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 92 | 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 93 | 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 94 | 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 95 | 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 96 | 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 97 | 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 98 | 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 99 | 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 100 | 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 101 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 102 | 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 103 | 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 104 | 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 105 | 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 106 | 0xf9, 0xfa 107 | }; 108 | 109 | static unsigned char STD_AC_UV_NRCODES[17]={0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0X77}; 110 | 111 | static unsigned char STD_AC_UV_VALUES[162]={ 112 | 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 113 | 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 114 | 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 115 | 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 116 | 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 117 | 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 118 | 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 119 | 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 120 | 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 121 | 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 122 | 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 123 | 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 124 | 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 125 | 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 126 | 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 127 | 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 128 | 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 129 | 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 130 | 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 131 | 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 132 | 0xf9, 0xfa 133 | }; 134 | 135 | static unsigned short mask[16]={ 136 | 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768 137 | }; 138 | 139 | typedef struct tagJPEGAPP0{ 140 | unsigned short segmentTag; 141 | unsigned short length; 142 | char id[5]; 143 | unsigned short ver; 144 | unsigned char densityUnit; 145 | unsigned short densityX; 146 | unsigned short densityY; 147 | unsigned char thp; 148 | unsigned char tvp; 149 | }JPEGAPP0; 150 | 151 | typedef struct tagJPEGDQT_8BITS{ 152 | unsigned short segmentTag; 153 | unsigned short length; 154 | unsigned char tableInfo; 155 | unsigned char table[64]; 156 | }JPEGDQT_8BITS; 157 | 158 | typedef struct tagJPEGSOF0_24BITS{ 159 | unsigned short segmentTag; 160 | unsigned short length; 161 | unsigned char precision; 162 | unsigned short height; 163 | unsigned short width; 164 | unsigned char sigNum; 165 | unsigned char YID; 166 | unsigned char HVY; 167 | unsigned char QTY; 168 | unsigned char UID; 169 | unsigned char HVU; 170 | unsigned char QTU; 171 | unsigned char VID; 172 | unsigned char HVV; 173 | unsigned char QTV; 174 | }JPEGSOF0_24BITS; 175 | 176 | typedef struct tagJPEGDHT{ 177 | unsigned short segmentTag; 178 | unsigned short length; 179 | unsigned char tableInfo; 180 | unsigned char huffCode[16]; 181 | }JPEGDHT; 182 | 183 | typedef struct tagJPEGSOS_24BITS{ 184 | unsigned short segmentTag; 185 | unsigned short length; 186 | unsigned char sigNum; 187 | unsigned char YID; 188 | unsigned char HTY; 189 | unsigned char UID; 190 | unsigned char HTU; 191 | unsigned char VID; 192 | unsigned char HTV; 193 | unsigned char Ss; 194 | unsigned char Se; 195 | unsigned char Bf; 196 | }JPEGSOS_24BITS; 197 | 198 | typedef struct tagACSYM{ 199 | unsigned char zeroLen; 200 | unsigned char codeLen; 201 | short amplitude; 202 | }ACSYM; 203 | 204 | typedef struct tagSYM2{ 205 | short amplitude; 206 | unsigned char codeLen; 207 | }SYM2; 208 | 209 | typedef struct tagBMBUFINFO{ 210 | unsigned int imgWidth; 211 | unsigned int imgHeight; 212 | unsigned int buffWidth; 213 | unsigned int buffHeight; 214 | unsigned short BitCount; 215 | unsigned char padSize; 216 | }BMBUFINFO; 217 | 218 | void ProcessUV(unsigned char* pUVBuf,unsigned char* pTmpUVBuf,int width,int height,int nStride); 219 | int QualityScaling(int quality); 220 | void DivBuff(unsigned char* pBuf,int width,int height,int nStride,int xLen,int yLen); 221 | void SetQuantTable(unsigned char* std_QT,unsigned char* QT, int Q); 222 | void InitQTForAANDCT(JPEGINFO *pJpgInfo); 223 | void BuildVLITable(JPEGINFO *pJpgInfo); 224 | int WriteSOI(unsigned char* pOut,int nDataLen); 225 | int WriteEOI(unsigned char* pOut,int nDataLen); 226 | int WriteAPP0(unsigned char* pOut,int nDataLen); 227 | int WriteDQT(JPEGINFO *pJpgInfo,unsigned char* pOut,int nDataLen); 228 | int WriteSOF(unsigned char* pOut,int nDataLen,int width,int height); 229 | int WriteDHT(unsigned char* pOut,int nDataLen); 230 | int WriteSOS(unsigned char* pOut,int nDataLen); 231 | void BuildSTDHuffTab(unsigned char* nrcodes,unsigned char* stdTab,HUFFCODE* huffCode); 232 | int ProcessData(JPEGINFO *pJpgInfo,unsigned char* lpYBuf,unsigned char* lpUBuf,unsigned char* lpVBuf,int width,int height,int yBufLen, int uBufLen,int vBufLen,unsigned char* pOut,int nDataLen); 233 | int YUV2Jpg(unsigned char* in_Y,unsigned char* in_U,unsigned char* in_V,int width,int height,int quality,int nStride,unsigned char* pOut,unsigned long *pnOutSize); 234 | #endif 235 | --------------------------------------------------------------------------------