/// <summary> /// 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB /// </summary> private static void putcontig8bitYCbCr12tile( TiffRgbaImage img, int[] raster, int rasterOffset, int rasterShift, int x, int y, int width, int height, byte[] buffer, int offset, int bufferShift) { bufferShift = (bufferShift / 2) * 4; int rasterOffset2 = rasterOffset + width + rasterShift; while (height >= 2) { x = width; do { int Cb = buffer[offset + 2]; int Cr = buffer[offset + 3]; img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 0], buffer[offset + 1], Cb, Cr); rasterOffset++; rasterOffset2++; offset += 4; } while (--x != 0); rasterOffset += rasterShift * 2 + width; rasterOffset2 += rasterShift * 2 + width; offset += bufferShift; height -= 2; } if (height == 1) { x = width; do { int Cb = buffer[offset + 2]; int Cr = buffer[offset + 3]; img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); rasterOffset++; offset += 4; } while (--x != 0); } }
/// <summary> /// 8-bit packed YCbCr samples w/ no subsampling => RGB /// </summary> private static void putcontig8bitYCbCr11tile( TiffRgbaImage img, int[] raster, int rasterOffset, int rasterShift, int x, int y, int width, int height, byte[] buffer, int offset, int bufferShift) { bufferShift *= 3; do { x = width; // was x = w >> 1; patched 2000/09/25 [email protected] do { int Cb = buffer[offset + 1]; int Cr = buffer[offset + 2]; img.YCbCrtoRGB(out raster[rasterOffset], buffer[offset + 0], Cb, Cr); rasterOffset++; offset += 3; } while (--x != 0); rasterOffset += rasterShift; offset += bufferShift; } while (--height != 0); }
/// <summary> /// 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB /// </summary> private static void putcontig8bitYCbCr41tile( TiffRgbaImage img, int[] raster, int rasterOffset, int rasterShift, int x, int y, int width, int height, byte[] buffer, int offset, int bufferShift) { // XXX adjust bufferShift do { x = width >> 2; do { int Cb = buffer[offset + 4]; int Cr = buffer[offset + 5]; img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 2], buffer[offset + 2], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 3], buffer[offset + 3], Cb, Cr); rasterOffset += 4; offset += 6; } while (--x != 0); if ((width & 3) != 0) { int Cb = buffer[offset + 4]; int Cr = buffer[offset + 5]; int xx = width & 3; if (xx == 3) img.YCbCrtoRGB(out raster[rasterOffset + 2], buffer[offset + 2], Cb, Cr); if (xx == 3 || xx == 2) img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); if (xx == 3 || xx == 2 || xx == 1) img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); rasterOffset += xx; offset += 6; } rasterOffset += rasterShift; offset += bufferShift; } while (--height != 0); }
/// <summary> /// 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB /// </summary> private static void putcontig8bitYCbCr42tile( TiffRgbaImage img, int[] raster, int rasterOffset, int rasterShift, int x, int y, int width, int height, byte[] buffer, int offset, int bufferShift) { int rasterOffset2 = rasterOffset + width + rasterShift; int incr = 2 * rasterShift + width; bufferShift = (bufferShift * 10) / 4; if ((height & 3) == 0 && (width & 1) == 0) { for (; height >= 2; height -= 2) { x = width >> 2; do { int Cb = buffer[offset + 8]; int Cr = buffer[offset + 9]; img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 2], buffer[offset + 2], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 3], buffer[offset + 3], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 0], buffer[offset + 4], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 1], buffer[offset + 5], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 2], buffer[offset + 6], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 3], buffer[offset + 7], Cb, Cr); rasterOffset += 4; rasterOffset2 += 4; offset += 10; } while (--x != 0); rasterOffset += incr; rasterOffset2 += incr; offset += bufferShift; } } else { while (height > 0) { for (x = width; x > 0; ) { int Cb = buffer[offset + 8]; int Cr = buffer[offset + 9]; bool x_goOn = false; if (x < 1 || x > 3) { if (height != 1) img.YCbCrtoRGB(out raster[rasterOffset2 + 3], buffer[offset + 7], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 3], buffer[offset + 3], Cb, Cr); x_goOn = true; } if (x == 3 || x_goOn) { if (height != 1) img.YCbCrtoRGB(out raster[rasterOffset2 + 2], buffer[offset + 6], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 2], buffer[offset + 2], Cb, Cr); x_goOn = true; } if (x == 2 || x_goOn) { if (height != 1) img.YCbCrtoRGB(out raster[rasterOffset2 + 1], buffer[offset + 5], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); x_goOn = true; } if (x == 1 || x_goOn) { if (height != 1) img.YCbCrtoRGB(out raster[rasterOffset2 + 0], buffer[offset + 4], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); } if (x < 4) { rasterOffset += x; rasterOffset2 += x; x = 0; } else { rasterOffset += 4; rasterOffset2 += 4; x -= 4; } offset += 10; } if (height <= 2) break; height -= 2; rasterOffset += incr; rasterOffset2 += incr; offset += bufferShift; } } }
/// <summary> /// 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB /// </summary> private static void putcontig8bitYCbCr44tile( TiffRgbaImage img, int[] raster, int rasterOffset, int rasterShift, int x, int y, int width, int height, byte[] buffer, int offset, int bufferShift) { int rasterOffset1 = rasterOffset + width + rasterShift; int rasterOffset2 = rasterOffset1 + width + rasterShift; int rasterOffset3 = rasterOffset2 + width + rasterShift; int incr = 3 * width + 4 * rasterShift; // adjust bufferShift bufferShift = (bufferShift * 18) / 4; if ((height & 3) == 0 && (width & 3) == 0) { for (; height >= 4; height -= 4) { x = width >> 2; do { int Cb = buffer[offset + 16]; int Cr = buffer[offset + 17]; img.YCbCrtoRGB(out raster[rasterOffset], buffer[offset + 0], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 2], buffer[offset + 2], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 3], buffer[offset + 3], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset1 + 0], buffer[offset + 4], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset1 + 1], buffer[offset + 5], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset1 + 2], buffer[offset + 6], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset1 + 3], buffer[offset + 7], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 0], buffer[offset + 8], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 1], buffer[offset + 9], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 2], buffer[offset + 10], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset2 + 3], buffer[offset + 11], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset3 + 0], buffer[offset + 12], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset3 + 1], buffer[offset + 13], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset3 + 2], buffer[offset + 14], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset3 + 3], buffer[offset + 15], Cb, Cr); rasterOffset += 4; rasterOffset1 += 4; rasterOffset2 += 4; rasterOffset3 += 4; offset += 18; } while (--x != 0); rasterOffset += incr; rasterOffset1 += incr; rasterOffset2 += incr; rasterOffset3 += incr; offset += bufferShift; } } else { while (height > 0) { for (x = width; x > 0; ) { int Cb = buffer[offset + 16]; int Cr = buffer[offset + 17]; bool h_goOn = false; bool x_goOn = false; // order of if's is important if (x < 1 || x > 3) { // order of if's is important h_goOn = false; if (height < 1 || height > 3) { img.YCbCrtoRGB(out raster[rasterOffset3 + 3], buffer[offset + 15], Cb, Cr); h_goOn = true; } if (height == 3 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset2 + 3], buffer[offset + 11], Cb, Cr); h_goOn = true; } if (height == 2 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset1 + 3], buffer[offset + 7], Cb, Cr); h_goOn = true; } if (height == 1 || h_goOn) img.YCbCrtoRGB(out raster[rasterOffset + 3], buffer[offset + 3], Cb, Cr); x_goOn = true; } if (x == 3 || x_goOn) { // order of if's is important h_goOn = false; if (height < 1 || height > 3) { img.YCbCrtoRGB(out raster[rasterOffset3 + 2], buffer[offset + 14], Cb, Cr); h_goOn = true; } if (height == 3 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset2 + 2], buffer[offset + 10], Cb, Cr); h_goOn = true; } if (height == 2 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset1 + 2], buffer[offset + 6], Cb, Cr); h_goOn = true; } if (height == 1 || h_goOn) img.YCbCrtoRGB(out raster[rasterOffset + 2], buffer[offset + 2], Cb, Cr); x_goOn = true; } if (x == 2 || x_goOn) { // order of if's is important h_goOn = false; if (height < 1 || height > 3) { img.YCbCrtoRGB(out raster[rasterOffset3 + 1], buffer[offset + 13], Cb, Cr); h_goOn = true; } if (height == 3 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset2 + 1], buffer[offset + 9], Cb, Cr); h_goOn = true; } if (height == 2 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset1 + 1], buffer[offset + 5], Cb, Cr); h_goOn = true; } if (height == 1 || h_goOn) img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); } if (x == 1 || x_goOn) { // order of if's is important h_goOn = false; if (height < 1 || height > 3) { img.YCbCrtoRGB(out raster[rasterOffset3 + 0], buffer[offset + 12], Cb, Cr); h_goOn = true; } if (height == 3 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset2 + 0], buffer[offset + 8], Cb, Cr); h_goOn = true; } if (height == 2 || h_goOn) { img.YCbCrtoRGB(out raster[rasterOffset1 + 0], buffer[offset + 4], Cb, Cr); h_goOn = true; } if (height == 1 || h_goOn) img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); } if (x < 4) { rasterOffset += x; rasterOffset1 += x; rasterOffset2 += x; rasterOffset3 += x; x = 0; } else { rasterOffset += 4; rasterOffset1 += 4; rasterOffset2 += 4; rasterOffset3 += 4; x -= 4; } offset += 18; } if (height <= 4) break; height -= 4; rasterOffset += incr; rasterOffset1 += incr; rasterOffset2 += incr; rasterOffset3 += incr; offset += bufferShift; } } }
/// <summary> /// 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB /// </summary> private static void putcontig8bitYCbCr21tile( TiffRgbaImage img, int[] raster, int rasterOffset, int rasterShift, int x, int y, int width, int height, byte[] buffer, int offset, int bufferShift) { bufferShift = (bufferShift * 4) / 2; do { x = width >> 1; do { int Cb = buffer[offset + 2]; int Cr = buffer[offset + 3]; img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); img.YCbCrtoRGB(out raster[rasterOffset + 1], buffer[offset + 1], Cb, Cr); rasterOffset += 2; offset += 4; } while (--x != 0); if ((width & 1) != 0) { int Cb = buffer[offset + 2]; int Cr = buffer[offset + 3]; img.YCbCrtoRGB(out raster[rasterOffset + 0], buffer[offset + 0], Cb, Cr); rasterOffset += 1; offset += 4; } rasterOffset += rasterShift; offset += bufferShift; } while (--height != 0); }