package org.alivepdf.encoding
{
import flash.display.BitmapData;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
import flash.utils.ByteArray;
import org.alivepdf.encoding.BitString;
import org.alivepdf.encoding.IntBlock;
import org.alivepdf.encoding.IntList;
/**
* Class that converts BitmapData into a valid JPEG
*/
public final class JPEGEncoder {
private static const ZigZagList:IntList = IntList.create([
0, 1, 5, 6,14,15,27,28,
2, 4, 7,13,16,26,29,42,
3, 8,12,17,25,30,41,43,
9,11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63
]);
private static const YQTList:IntList = IntList.create([
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, 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
]);
private static const UVQTList:IntList = IntList.create([
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,
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
]);
private static const aasf:Array = [
1.0, 1.387039845, 1.306562965, 1.175875602,
1.0, 0.785694958, 0.541196100, 0.275899379
];
private static const aanscalesList:IntList = IntList.create([
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
]);
private const YTable:Array = new Array(64);
private const UVTable:Array = new Array(64);
private const fdtbl_YList:IntList = IntList.create(new Array(64));
private const fdtbl_UVList:IntList = IntList.create(new Array(64));
private function initQuantTables(sf:int):void {
var i:int;
var t:int;
var ZigZag:IntList = ZigZagList;
var YQT:IntList = YQTList;
for (i = 0; i < 64; ++i) {
t = ((YQTList.data*sf+50)/100);
YQT = YQT.next;
if (t < 1) {
t = 1;
} else if (t > 255) {
t = 255;
}
YTable[ZigZag.data] = t;
ZigZag = ZigZag.next;
}
ZigZag = ZigZagList;
var UVQT:IntList = UVQTList;
for (i = 0; i < 64; ++i) {
t = ((UVQT.data*sf+50)/100);
UVQT = UVQT.next;
if (t < 1) {
t = 1;
} else if (t > 255) {
t = 255;
}
UVTable[ZigZag.data] = t;
ZigZag = ZigZag.next;
}
ZigZag = ZigZagList;
var fdtbl_Y:IntList = fdtbl_YList;
var fdtbl_UV:IntList = fdtbl_UVList;
for (i = 0; i < 64; ++i) {
fdtbl_Y.data = YTable[ZigZag.data] << 3;
fdtbl_UV.data = UVTable[ZigZag.data] << 3;
ZigZag = ZigZag.next;
fdtbl_Y = fdtbl_Y.next;
fdtbl_UV = fdtbl_UV.next;
}
}
private static const std_dc_luminance_nrcodesList:IntList = IntList.create([0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]);
private static const std_dc_luminance_valuesList:IntList = IntList.create([0,1,2,3,4,5,6,7,8,9,10,11]);
private static const std_ac_luminance_nrcodesList:IntList = IntList.create([0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]);
private static const std_ac_luminance_valuesList:IntList = IntList.create([
0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
0xf9,0xfa
]);
private static const std_dc_chrominance_nrcodesList:IntList = IntList.create([0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]);
private static const std_dc_chrominance_valuesList:IntList = IntList.create([0,1,2,3,4,5,6,7,8,9,10,11]);
private static const std_ac_chrominance_nrcodesList:IntList = IntList.create([0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]);
private static const std_ac_chrominance_valuesList:IntList = IntList.create([
0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
0xf9,0xfa
]);
private function computeHuffmanTbl(nrcodesList:IntList, std_tableList:IntList):Array {
var codevalue:int = 0;
var nrcodes:IntList = nrcodesList.next;
var std_table:IntList = std_tableList;
var HT:Array = new Array(251);
for (var k:int = 1; k <= 16; ++k) {
var nr:int = nrcodes.data;
for (var j:int=1; j<=nr; ++j) {
HT[std_table.data] = new BitString(codevalue, k);
std_table = std_table.next;
++codevalue;
}
nrcodes = nrcodes.next;
codevalue<<=1;
}
return HT;
}
private var YDC_HT:Array;
private var UVDC_HT:Array;
private var YAC_HT:Array;
private var UVAC_HT:Array;
private function initHuffmanTbl():void {
YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodesList,std_dc_luminance_valuesList);
UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodesList,std_dc_chrominance_valuesList);
YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodesList,std_ac_luminance_valuesList);
UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodesList,std_ac_chrominance_valuesList);
}
private const bitcode:Array = new Array(65535);
private const category:Array = new Array(65535);
private function initCategoryNumber():void {
var nrlower:int = 1;
var nrupper:int = 2;
var nr:int;
var n:int;
for (var cat:int=1; cat<=15; ++cat) {
for (nr=nrlower; nr<nrupper; ++nr) {
n = 32767+nr;
category[n] = cat;
bitcode[n] = new BitString(nr, cat);
}
for (nr=-(nrupper-1); nr<=-nrlower; ++nr) {
n = 32767+nr;
category[n] = cat;
bitcode[n] = new BitString(nrupper-1+nr, cat);
}
nrlower <<= 1;
nrupper <<= 1;
}
}
private var byteout:ByteArray;
private var bytenew:int = 0;
private var bytepos:int = 7;
private function writeBits(bs:BitString):void {
var value:int = bs.val;
var posval:int = bs.len-1;
while ( posval >= 0 ) {
if (value & (1 << posval) ) {
bytenew |= (1 << bytepos);
}
posval--;
bytepos--;
if (bytepos < 0) {
if (bytenew == 0xFF) {
writeByte(0xFF);
writeByte(0);
}
else {
writeByte(bytenew);
}
bytepos=7;
bytenew=0;
}
}
}
private function writeByte(value:int):void {
byteout.writeByte(value);
}
private function writeWord(value:int):void {
writeByte((value>>8));
writeByte((value ));
}
private function fDCTQuant(data:IntBlock, fdtbl:IntList):IntBlock {
var tmp0:int, tmp1:int, tmp2:int, tmp3:int, tmp4:int, tmp5:int, tmp6:int, tmp7:int;
var tmp10:int, tmp11:int, tmp12:int, tmp13:int;
var d0:int, d1:int, d2:int, d3:int, d4:int, d5:int, d6:int, d7:int;
var z1:int, z2:int, z3:int, z4:int, z5:int;
var i:int;
var row:IntBlock, col:IntBlock;
var dataOff:IntBlock;
row = data;
for (i=0; i<8; ++i) {
dataOff = row;
d0 = dataOff.data;
dataOff = dataOff.next;
d1 = dataOff.data;
dataOff = dataOff.next;
d2 = dataOff.data;
dataOff = dataOff.next;
d3 = dataOff.data;
dataOff = dataOff.next;
d4 = dataOff.data;
dataOff = dataOff.next;
d5 = dataOff.data;
dataOff = dataOff.next;
d6 = dataOff.data;
dataOff = dataOff.next;
d7 = dataOff.data;
tmp0 = d0+d7;
tmp7 = d0-d7;
tmp1 = d1+d6;
tmp6 = d1-d6;
tmp2 = d2+d5;
tmp5 = d2-d5;
tmp3 = d3+d4;
tmp4 = d3-d4;
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
z1 = ((tmp12 + tmp13) * 4433);
dataOff = row;
dataOff.data = (tmp10 + tmp11) << 2;
dataOff = dataOff.next.next;
dataOff.data = (z1 + tmp13 * 6270 + (0x400)) >> 11;
dataOff = dataOff.next.next;
dataOff.data = (tmp10 - tmp11) << 2;
dataOff = dataOff.next.next;
dataOff.data = (z1 - tmp12 * 15137 + (0x400)) >> 11;
z1 = tmp4 + tmp7;
z2 = tmp5 + tmp6;
z3 = tmp4 + tmp6;
z4 = tmp5 + tmp7;
z5 = (z3 + z4) * 9633;
tmp4 = tmp4 * 2446;
tmp5 = tmp5 * 16819;
tmp6 = tmp6 * 25172;
tmp7 = tmp7 * 12299;
z1 = - z1 * 7373;
z2 = - z2 * 20995;
z3 = - z3 * 16069;
z4 = - z4 * 3196;
z3 += z5;
z4 += z5;
dataOff = row.next;
dataOff.data = (tmp7 + z1 + z4 + (0x400)) >> 11;
dataOff = dataOff.next.next;
dataOff.data = (tmp6 + z2 + z3 + (0x400)) >> 11;
dataOff = dataOff.next.next;
dataOff.data = (tmp5 + z2 + z4 + (0x400)) >> 11;
dataOff = dataOff.next.next;
dataOff.data = (tmp4 + z1 + z3 + (0x400)) >> 11;
row = row.down;
}
col = data;
for (i=0; i<8; ++i) {
dataOff = col;
d0 = dataOff.data;
dataOff = dataOff.down;
d1 = dataOff.data;
dataOff = dataOff.down;
d2 = dataOff.data;
dataOff = dataOff.down;
d3 = dataOff.data;
dataOff = dataOff.down;
d4 = dataOff.data;
dataOff = dataOff.down;
d5 = dataOff.data;
dataOff = dataOff.down;
d6 = dataOff.data;
dataOff = dataOff.down;
d7 = dataOff.data;
tmp0 = d0+d7;
tmp7 = d0-d7;
tmp1 = d1+d6;
tmp6 = d1-d6;
tmp2 = d2+d5;
tmp5 = d2-d5;
tmp3 = d3+d4;
tmp4 = d3-d4;
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
z1 = ((tmp12 + tmp13) * 4433);
dataOff = col;
dataOff.data = (tmp10 + tmp11 + (0x2)) >> 2;
dataOff = dataOff.down.down;
dataOff.data = (z1 + tmp13 * 6270 + (0x4000)) >> 15;
dataOff = dataOff.down.down;
dataOff.data = (tmp10 - tmp11 + (0x2)) >> 2;
dataOff = dataOff.down.down;
dataOff.data = (z1 - tmp12 * 15137 + (0x4000)) >> 15;
z1 = tmp4 + tmp7;
z2 = tmp5 + tmp6;
z3 = tmp4 + tmp6;
z4 = tmp5 + tmp7;
z5 = (z3 + z4) * 9633;
tmp4 = tmp4 * 2446;
tmp5 = tmp5 * 16819;
tmp6 = tmp6 * 25172;
tmp7 = tmp7 * 12299;
z1 = - z1 * 7373;
z2 = - z2 * 20995;
z3 = - z3 * 16069;
z4 = - z4 * 3196;
z3 += z5;
z4 += z5;
dataOff = col.down;
dataOff.data = (tmp7 + z1 + z4 + (0x4000)) >> 15;
dataOff = dataOff.down.down;
dataOff.data = (tmp6 + z2 + z3 + (0x4000)) >> 15;
dataOff = dataOff.down.down;
dataOff.data = (tmp5 + z2 + z4 + (0x4000)) >> 15;
dataOff = dataOff.down.down;
dataOff.data = (tmp4 + z1 + z3 + (0x4000)) >> 15;
col = col.next;
}
dataOff = data;
for (i=0; i<64; ++i) {
var qval:int = fdtbl.data;
fdtbl = fdtbl.next;
var temp:int = dataOff.data;
if (temp < 0) {
temp = -temp;
temp += qval >> 1;
if (temp >= qval) temp /= qval;
else temp = 0;
temp = -temp;
} else {
temp += qval >> 1;
if (temp >= qval) temp /= qval;
else temp = 0;
}
dataOff.data = temp;
dataOff = dataOff.next;
}
return data;
}
private function writeAPP0():void {
writeWord(0xFFE0); writeWord(16); writeByte(0x4A); writeByte(0x46); writeByte(0x49); writeByte(0x46); writeByte(0); writeByte(1); writeByte(1); writeByte(0); writeWord(1); writeWord(1); writeByte(0); writeByte(0); }
private function writeSOF0(width:int, height:int):void {
writeWord(0xFFC0); writeWord(17); writeByte(8); writeWord(height);
writeWord(width);
writeByte(3); writeByte(1); writeByte(0x11); writeByte(0); writeByte(2); writeByte(0x11); writeByte(1); writeByte(3); writeByte(0x11); writeByte(1); }
private function writeDQT():void {
writeWord(0xFFDB); writeWord(132); writeByte(0);
var i:int;
for (i=0; i<64; ++i) {
writeByte(YTable[i]);
}
writeByte(1);
for (i=0; i<64; ++i) {
writeByte(UVTable[i]);
}
}
private function writeDHT():void {
writeWord(0xFFC4); writeWord(0x01A2); var i:int;
writeByte(0); var std_dc_luminance_nrcodes:IntList = std_dc_luminance_nrcodesList.next;
for (i=1; i<=16; ++i) {
writeByte(std_dc_luminance_nrcodes.data);
std_dc_luminance_nrcodes = std_dc_luminance_nrcodes.next;
}
var std_dc_luminance_values:IntList = std_dc_luminance_valuesList;
for (i=0; i<=11; ++i) {
writeByte(std_dc_luminance_values.data);
std_dc_luminance_values = std_dc_luminance_values.next;
}
writeByte(0x10); var std_ac_luminance_nrcodes:IntList = std_ac_luminance_nrcodesList.next;
for (i=1; i<=16; ++i) {
writeByte(std_ac_luminance_nrcodes.data);
std_ac_luminance_nrcodes = std_ac_luminance_nrcodes.next;
}
var std_ac_luminance_values:IntList = std_ac_luminance_valuesList;
for (i=0; i<=161; ++i) {
writeByte(std_ac_luminance_values.data);
std_ac_luminance_values = std_ac_luminance_values.next;
}
writeByte(1); var std_dc_chrominance_nrcodes:IntList = std_dc_chrominance_nrcodesList.next;
for (i=1; i<=16; ++i) {
writeByte(std_dc_chrominance_nrcodes.data);
std_dc_chrominance_nrcodes = std_dc_chrominance_nrcodes.next;
}
var std_dc_chrominance_values:IntList = std_dc_chrominance_valuesList;
for (i=0; i<=11; ++i) {
writeByte(std_dc_chrominance_values.data);
std_dc_chrominance_values = std_dc_chrominance_values.next;
}
writeByte(0x11); var std_ac_chrominance_nrcodes:IntList = std_ac_chrominance_nrcodesList.next;
for (i=1; i<=16; ++i) {
writeByte(std_ac_chrominance_nrcodes.data);
std_ac_chrominance_nrcodes = std_ac_chrominance_nrcodes.next;
}
var std_ac_chrominance_values:IntList = std_ac_chrominance_valuesList;
for (i=0; i<=161; ++i) {
writeByte(std_ac_chrominance_values.data);
std_ac_chrominance_values = std_ac_chrominance_values.next;
}
}
private function writeSOS():void {
writeWord(0xFFDA); writeWord(12); writeByte(3); writeByte(1); writeByte(0); writeByte(2); writeByte(0x11); writeByte(3); writeByte(0x11); writeByte(0); writeByte(0x3f); writeByte(0); }
private const DU:Array = new Array(64);
private function processDU(CDU:IntBlock, fdtbl:IntList, DC:int, HTDC:Array, HTAC:Array):int {
var EOB:BitString = HTAC[0x00];
var M16zeroes:BitString = HTAC[0xF0];
var i:int;
var DU_DCT:IntBlock = fDCTQuant(CDU, fdtbl);
var ZigZag:IntList = ZigZagList;
for (i=0;i<64;++i) {
DU[ZigZag.data] = DU_DCT.data;
ZigZag = ZigZag.next;
DU_DCT = DU_DCT.next;
}
var Diff:int = DU[0] - DC; DC = DU[0];
if (Diff==0) {
writeBits(HTDC[0]); } else {
i = 32767+Diff;
writeBits(HTDC[category[i]>>0]);
writeBits(bitcode[i]);
}
var end0pos:int = 63;
while((end0pos>0)&&(DU[end0pos]==0)) --end0pos;
if ( end0pos == 0) {
writeBits(EOB);
return DC;
}
i = 1;
while ( i <= end0pos ) {
var startpos:int = i;
while((DU[i]==0) && (i<=end0pos)) ++i;
var nrzeroes:int = i-startpos;
var n:int;
if ( nrzeroes >= 16 ) {
n = nrzeroes/16;
for (var nrmarker:int=1; nrmarker <= n; ++nrmarker) {
writeBits(M16zeroes);
}
nrzeroes = (nrzeroes&0xF);
}
n = 32767+DU[i];
writeBits(HTAC[((nrzeroes<<4)+category[n])>>0]);
writeBits(bitcode[n]);
++i;
}
if ( end0pos != 63 ) {
writeBits(EOB);
}
return DC;
}
private const YDUBlock:IntBlock = IntBlock.create8_8(new Array(64));
private const UDUBlock:IntBlock = IntBlock.create8_8(new Array(64));
private const VDUBlock:IntBlock = IntBlock.create8_8(new Array(64));
private static const fltrRGB2YUV:ColorMatrixFilter = new ColorMatrixFilter([
0.29900, 0.58700, 0.11400, 0, 0,
-0.16874, -0.33126, 0.50000, 0, 128,
0.50000, -0.41869, -0.08131, 0, 128,
0, 0, 0, 1, 0
]);
private static const orgn:Point = new Point();
private function RGB2YUV(img:BitmapData, xpos:int, ypos:int):void {
var YDU:IntBlock = YDUBlock;
var UDU:IntBlock = UDUBlock;
var VDU:IntBlock = VDUBlock;
for (var y:int=0; y<8; ++y) {
for (var x:int=0; x<8; ++x) {
var P:int = img.getPixel(xpos+x,ypos+y);
var R:int = ((P>>16)&0xFF);
var G:int = ((P>> 8)&0xFF);
var B:int = ((P )&0xFF);
YDU.data = R-128;
UDU.data = G-128;
VDU.data = B-128;
YDU = YDU.next;
UDU = UDU.next;
VDU = VDU.next;
}
}
}
/**
* Constructor for JPEGEncoder class
*
* @param quality The quality level between 1 and 100 that detrmines the
* level of compression used in the generated JPEG
* @param dct The forward DCT method to use,
* supported methods: JDCT_ISLOW, JDCT_IFAST, JDCT_FLOAT
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
public function JPEGEncoder(quality:Number = 50) {
if (quality <= 0) {
quality = 1;
}
if (quality > 100) {
quality = 100;
}
var sf:int = 0;
if (quality < 50) {
sf = (5000 / quality);
} else {
sf = (200 - quality*2);
}
initHuffmanTbl();
initCategoryNumber();
initQuantTables(sf);
}
/**
* Created a JPEG image from the specified BitmapData
*
* @param image The BitmapData that will be converted into the JPEG format.
* @return a ByteArray representing the JPEG encoded image data.
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
public function encode(image:BitmapData):ByteArray {
var img:BitmapData = image.clone();
img.applyFilter(img, img.rect, orgn, fltrRGB2YUV);
var height:int = img.height;
var width:int = img.width;
byteout = new ByteArray();
bytenew=0;
bytepos=7;
writeWord(0xFFD8); writeAPP0();
writeDQT();
writeSOF0(width,height);
writeDHT();
writeSOS();
var DCY:int=0;
var DCU:int=0;
var DCV:int=0;
for (var ypos:int=0; ypos<height; ypos+=8) {
for (var xpos:int=0; xpos<width; xpos+=8) {
RGB2YUV(img, xpos, ypos);
DCY = processDU(YDUBlock, fdtbl_YList, DCY, YDC_HT, YAC_HT);
DCU = processDU(UDUBlock, fdtbl_UVList, DCU, UVDC_HT, UVAC_HT);
DCV = processDU(VDUBlock, fdtbl_UVList, DCV, UVDC_HT, UVAC_HT);
}
}
img.dispose();
if ( bytepos >= 0 ) {
writeBits(new BitString((1<<(bytepos+1))-1, bytepos+1));
}
writeWord(0xFFD9); return byteout;
}
}
}