private static UInt32 readNBits(ref CAmigaUnpackData amiga, UInt32 n) { if (amiga.data == null || amiga.data.Length <= amiga.readPosition) return 0; UInt32 returnValue = 0; try { for (Int32 i = 0; i < n; i++) { if (amiga.counter <= 0) { amiga.counter = 8; amiga.readPosition--; amiga.currentByte = amiga.data[amiga.readPosition]; } returnValue = (UInt32)((returnValue << 1) | (UInt32)(amiga.currentByte & 0x01)); amiga.currentByte >>= 1; amiga.counter--; } } catch (SystemException) { return 0; } return returnValue; }
public static byte[] unpackAmiga2Data(ref byte[] sourceData, Int32 startPosition, Int32 dataLength) { if (sourceData == null || (startPosition + dataLength) >= sourceData.Length) return null; UInt32 unpackLength = sourceData[startPosition + dataLength - 2]; unpackLength += (UInt32)(sourceData[startPosition + dataLength - 3] << 8); unpackLength += (UInt32)(sourceData[startPosition + dataLength - 4] << 16); byte[] returnData = new byte[unpackLength]; UInt32 destinationPosition = (UInt32)(unpackLength); CAmigaUnpackData amiga = new CAmigaUnpackData(ref sourceData, startPosition + dataLength - 4); //---zum Entpacken--- UInt32 anzahlWiederholungen = 0; byte[] offsetSizes = new byte[4]; offsetSizes[0] = sourceData[startPosition + 4]; offsetSizes[1] = sourceData[startPosition + 5]; offsetSizes[2] = sourceData[startPosition + 6]; offsetSizes[3] = sourceData[startPosition + 7]; //------------------- UInt32 x = 0; //skip some bits readNBits(ref amiga, sourceData[startPosition + dataLength - 1]); while (destinationPosition != 0) { if (0 == readNBits(ref amiga, 1)) { //daten sind nicht gepackt anzahlWiederholungen = 0; do { x = readNBits(ref amiga, 2); anzahlWiederholungen += x; } while (x == 3); // wenn nicht alle bits ge for (int i = 0; i <= anzahlWiederholungen; i++) returnData[--destinationPosition] = (byte)readNBits(ref amiga, 8); if (destinationPosition == 0) break; } //daten sind gepackt x = readNBits(ref amiga, 2); UInt32 n_bits = offsetSizes[x]; UInt32 offset = 0; anzahlWiederholungen = x + 1; if (x == 3) { if (readNBits(ref amiga, 1) == 0) offset = readNBits(ref amiga, 7); else offset = readNBits(ref amiga, n_bits); do { x = readNBits(ref amiga, 3); anzahlWiederholungen += x; } while (x == 7); } else offset = readNBits(ref amiga, n_bits); for (int i = 0; i <= anzahlWiederholungen; i++) { try { returnData[destinationPosition - 1] = returnData[destinationPosition + offset]; destinationPosition--; } catch (SystemException) { return null; //throw e; } } if (destinationPosition == 0) return returnData; } return returnData; }