js-dicom
Version:
this is js-dicom
114 lines (88 loc) • 3.61 kB
JavaScript
function decodeRLE (imageFrame, pixelData) {
if (imageFrame.bitsAllocated === 8) {
return decode8(imageFrame, pixelData);
} else if (imageFrame.bitsAllocated === 16) {
return decode16(imageFrame, pixelData);
}
throw 'unsupported pixel format for RLE';
}
function decode8 (imageFrame, pixelData) {
const frameData = pixelData;
const frameSize = imageFrame.rows * imageFrame.columns;
const outFrame = new ArrayBuffer(frameSize * imageFrame.samplesPerPixel);
const header = new DataView(frameData.buffer, frameData.byteOffset);
const data = new Int8Array(frameData.buffer, frameData.byteOffset);
const out = new Int8Array(outFrame);
let outIndex = 0;
const numSegments = header.getInt32(0, true);
for (let s = 0; s < numSegments; ++s) {
outIndex = s;
let inIndex = header.getInt32((s + 1) * 4, true);
let maxIndex = header.getInt32((s + 2) * 4, true);
if (maxIndex === 0) {
maxIndex = frameData.length;
}
const endOfSegment = frameSize * numSegments;
while (inIndex < maxIndex) {
const n = data[inIndex++];
if (n >= 0 && n <= 127) {
// copy n bytes
for (let i = 0; i < n + 1 && outIndex < endOfSegment; ++i) {
out[outIndex] = data[inIndex++];
outIndex += imageFrame.samplesPerPixel;
}
} else if (n <= -1 && n >= -127) {
const value = data[inIndex++];
// run of n bytes
for (let j = 0; j < -n + 1 && outIndex < endOfSegment; ++j) {
out[outIndex] = value;
outIndex += imageFrame.samplesPerPixel;
}
}/* else if (n === -128) {
} // do nothing */
}
}
imageFrame.pixelData = new Uint8Array(outFrame);
return imageFrame;
}
function decode16 (imageFrame, pixelData) {
const frameData = pixelData;
const frameSize = imageFrame.rows * imageFrame.columns;
const outFrame = new ArrayBuffer(frameSize * imageFrame.samplesPerPixel * 2);
const header = new DataView(frameData.buffer, frameData.byteOffset);
const data = new Int8Array(frameData.buffer, frameData.byteOffset);
const out = new Int8Array(outFrame);
const numSegments = header.getInt32(0, true);
for (let s = 0; s < numSegments; ++s) {
let outIndex = 0;
const highByte = (s === 0 ? 1 : 0);
let inIndex = header.getInt32((s + 1) * 4, true);
let maxIndex = header.getInt32((s + 2) * 4, true);
if (maxIndex === 0) {
maxIndex = frameData.length;
}
while (inIndex < maxIndex) {
const n = data[inIndex++];
if (n >= 0 && n <= 127) {
for (let i = 0; i < n + 1 && outIndex < frameSize; ++i) {
out[(outIndex * 2) + highByte] = data[inIndex++];
outIndex++;
}
} else if (n <= -1 && n >= -127) {
const value = data[inIndex++];
for (let j = 0; j < -n + 1 && outIndex < frameSize; ++j) {
out[(outIndex * 2) + highByte] = value;
outIndex++;
}
}/* else if (n === -128) {
} // do nothing */
}
}
if (imageFrame.pixelRepresentation === 0) {
imageFrame.pixelData = new Uint16Array(outFrame);
} else {
imageFrame.pixelData = new Int16Array(outFrame);
}
return imageFrame;
}
export default decodeRLE;