1407 static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0};
1408 static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1409 static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d};
1410 static const unsigned char std_ac_luminance_values[] = {
1411 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
1412 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
1413 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
1414 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1415 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
1416 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
1417 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1419 static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};
1420 static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1421 static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};
1422 static const unsigned char std_ac_chrominance_values[] = {
1423 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
1424 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
1425 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
1426 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
1427 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
1428 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
1429 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1432 static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}};
1433 static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}};
1434 static const unsigned short YAC_HT[256][2] = {
1435 {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1436 {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1437 {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1438 {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1439 {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1440 {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1441 {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1442 {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1443 {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1444 {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1445 {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1446 {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1447 {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1448 {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1449 {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0},
1450 {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
1452 static const unsigned short UVAC_HT[256][2] = {
1453 {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1454 {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1455 {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1456 {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1457 {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1458 {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1459 {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1460 {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1461 {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1462 {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1463 {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1464 {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1465 {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1466 {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1467 {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0},
1468 {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
1470 static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,
1471 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
1472 static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
1473 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
1474 static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1475 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
1477 int row, col, i, k, subsample;
1478 float fdtbl_Y[64], fdtbl_UV[64];
1479 unsigned char YTable[64], UVTable[64];
1481 if(!data || !width || !height || comp > 4 || comp < 1) {
1485 quality = quality ? quality : 90;
1486 subsample = quality <= 90 ? 1 : 0;
1487 quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
1488 quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
1490 for(i = 0; i < 64; ++i) {
1491 int uvti, yti = (YQT[i]*quality+50)/100;
1492 YTable[
jpg_zig_zag[i]] = (
unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti);
1493 uvti = (UVQT[i]*quality+50)/100;
1494 UVTable[
jpg_zig_zag[i]] = (
unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
1497 for(row = 0, k = 0; row < 8; ++row) {
1498 for(col = 0; col < 8; ++col, ++k) {
1499 fdtbl_Y[k] = 1 / (YTable [
jpg_zig_zag[k]] * aasf[row] * aasf[col]);
1500 fdtbl_UV[k] = 1 / (UVTable[
jpg_zig_zag[k]] * aasf[row] * aasf[col]);
1506 static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,
'J',
'F',
'I',
'F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
1507 static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
1509 3,1,(
unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
1511 s->
func(s->
context, (
void*)YTable,
sizeof(YTable));
1515 s->
func(s->
context, (
void*)(std_dc_luminance_nrcodes+1),
sizeof(std_dc_luminance_nrcodes)-1);
1516 s->
func(s->
context, (
void*)std_dc_luminance_values,
sizeof(std_dc_luminance_values));
1518 s->
func(s->
context, (
void*)(std_ac_luminance_nrcodes+1),
sizeof(std_ac_luminance_nrcodes)-1);
1519 s->
func(s->
context, (
void*)std_ac_luminance_values,
sizeof(std_ac_luminance_values));
1521 s->
func(s->
context, (
void*)(std_dc_chrominance_nrcodes+1),
sizeof(std_dc_chrominance_nrcodes)-1);
1522 s->
func(s->
context, (
void*)std_dc_chrominance_values,
sizeof(std_dc_chrominance_values));
1524 s->
func(s->
context, (
void*)(std_ac_chrominance_nrcodes+1),
sizeof(std_ac_chrominance_nrcodes)-1);
1525 s->
func(s->
context, (
void*)std_ac_chrominance_values,
sizeof(std_ac_chrominance_values));
1531 static const unsigned short fillBits[] = {0x7F, 7};
1532 int DCY=0, DCU=0, DCV=0;
1533 int bitBuf=0, bitCnt=0;
1535 int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
1536 const unsigned char *dataR = (
const unsigned char *)data;
1537 const unsigned char *dataG = dataR + ofsG;
1538 const unsigned char *dataB = dataR + ofsB;
1541 for(y = 0; y < height; y += 16) {
1542 for(x = 0; x < width; x += 16) {
1543 float Y[256], U[256], V[256];
1544 for(row = y, pos = 0; row < y+16; ++row) {
1546 int clamped_row = (row < height) ? row : height - 1;
1548 for(col = x; col < x+16; ++col, ++pos) {
1550 int p = base_p + ((col < width) ? col : (width-1))*comp;
1551 float r = dataR[p], g = dataG[p], b = dataB[p];
1552 Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1553 U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1554 V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1557 DCY =
jpg_process_du(s, &bitBuf, &bitCnt,
Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1558 DCY =
jpg_process_du(s, &bitBuf, &bitCnt,
Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1559 DCY =
jpg_process_du(s, &bitBuf, &bitCnt,
Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1560 DCY =
jpg_process_du(s, &bitBuf, &bitCnt,
Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1564 float subU[64], subV[64];
1566 for(yy = 0, pos = 0; yy < 8; ++yy) {
1567 for(xx = 0; xx < 8; ++xx, ++pos) {
1569 subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f;
1570 subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f;
1573 DCU =
jpg_process_du(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1574 DCV =
jpg_process_du(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1579 for(y = 0; y < height; y += 8) {
1580 for(x = 0; x < width; x += 8) {
1581 float Y[64], U[64], V[64];
1582 for(row = y, pos = 0; row < y+8; ++row) {
1584 int clamped_row = (row < height) ? row : height - 1;
1586 for(col = x; col < x+8; ++col, ++pos) {
1588 int p = base_p + ((col < width) ? col : (width-1))*comp;
1589 float r = dataR[p], g = dataG[p], b = dataB[p];
1590 Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1591 U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1592 V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1596 DCY =
jpg_process_du(s, &bitBuf, &bitCnt,
Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1597 DCU =
jpg_process_du(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1598 DCV =
jpg_process_du(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);