def post_prediction(decodedStream, predictor, columns, colors, bits): ''' Predictor function to obtain the real stream, removing the prediction (PDF Specification) @param decodedStream: The decoded stream to be modified @param predictor: The type of predictor to apply @param columns: Number of samples per row @param colors: Number of colors per sample @param bits: Number of bits per color @return: A tuple (status,statusContent), where statusContent is the modified decoded stream in case status = 0 or an error in case status = -1 ''' output = '' bytesPerRow = (colors * bits * columns + 7) / 8 # TIFF - 2 # http://www.gnupdf.org/PNG_and_TIFF_Predictors_Filter#TIFF if predictor == 2: numRows = len(decodedStream) / bytesPerRow bitmask = 2**bits - 1 outputBitsStream = '' for rowIndex in range(numRows): row = decodedStream[rowIndex * bytesPerRow:rowIndex * bytesPerRow + bytesPerRow] ret, colorNums = getNumsFromBytes(row, bits) if ret == -1: return (ret, colorNums) pixel = [0 for x in range(colors)] for i in range(columns): for j in range(colors): diffPixel = colorNums[i + j] pixel[j] = (pixel[j] + diffPixel) & bitmask ret, outputBits = getBitsFromNum(pixel[j], bits) if ret == -1: return (ret, outputBits) outputBitsStream += outputBits output = getBytesFromBits(outputBitsStream) return output # PNG prediction # http://www.libpng.org/pub/png/spec/1.2/PNG-Filters.html # http://www.gnupdf.org/PNG_and_TIFF_Predictors_Filter#TIFF elif predictor >= 10 and predictor <= 15: bytesPerRow += 1 numRows = (len(decodedStream) + bytesPerRow - 1) / bytesPerRow numSamplesPerRow = columns + 1 bytesPerSample = (colors * bits + 7) / 8 upRowdata = (0, ) * numSamplesPerRow for row in xrange(numRows): rowdata = [ ord(x) for x in decodedStream[(row * bytesPerRow):((row + 1) * bytesPerRow)] ] # PNG prediction can vary from row to row filterByte = rowdata[0] rowdata[0] = 0 if filterByte == 0: # None pass elif filterByte == 1: # Sub - 11 for i in range(1, numSamplesPerRow): if i < bytesPerSample: prevSample = 0 else: prevSample = rowdata[i - bytesPerSample] rowdata[i] = (rowdata[i] + prevSample) % 256 elif filterByte == 2: # Up - 12 for i in range(1, numSamplesPerRow): upSample = upRowdata[i] rowdata[i] = (rowdata[i] + upSample) % 256 elif filterByte == 3: # Average - 13 for i in range(1, numSamplesPerRow): upSample = upRowdata[i] if i < bytesPerSample: prevSample = 0 else: prevSample = rowdata[i - bytesPerSample] rowdata[i] = (rowdata[i] + ((prevSample + upSample) / 2)) % 256 elif filterByte == 4: # Paeth - 14 for i in range(1, numSamplesPerRow): upSample = upRowdata[i] if i < bytesPerSample: prevSample = 0 upPrevSample = 0 else: prevSample = rowdata[i - bytesPerSample] upPrevSample = upRowdata[i - bytesPerSample] p = prevSample + upSample - upPrevSample pa = abs(p - prevSample) pb = abs(p - upSample) pc = abs(p - upPrevSample) if pa <= pb and pa <= pc: nearest = prevSample elif pb <= pc: nearest = upSample else: nearest = upPrevSample rowdata[i] = (rowdata[i] + nearest) % 256 else: # Optimum - 15 #return (-1,'Unsupported predictor') pass upRowdata = rowdata output += (''.join([chr(x) for x in rowdata[1:]])) return (0, output) else: return (-1, 'Wrong value for predictor')
def post_prediction(decodedStream, predictor, columns, colors, bits): ''' Predictor function to obtain the real stream, removing the prediction (PDF Specification) @param decodedStream: The decoded stream to be modified @param predictor: The type of predictor to apply @param columns: Number of samples per row @param colors: Number of colors per sample @param bits: Number of bits per color @return: A tuple (status,statusContent), where statusContent is the modified decoded stream in case status = 0 or an error in case status = -1 ''' output = '' bytesPerRow = (colors * bits * columns + 7) / 8 # TIFF - 2 # http://www.gnupdf.org/PNG_and_TIFF_Predictors_Filter#TIFF if predictor == 2: numRows = len(decodedStream) / bytesPerRow bitmask = 2 ** bits - 1 outputBitsStream = '' for rowIndex in range(numRows): row = decodedStream[rowIndex*bytesPerRow:rowIndex*bytesPerRow+bytesPerRow] ret,colorNums = getNumsFromBytes(row, bits) if ret == -1: return (ret,colorNums) pixel = [0 for x in range(colors)] for i in range(columns): for j in range(colors): diffPixel = colorNums[i+j] pixel[j] = (pixel[j] + diffPixel) & bitmask ret, outputBits = getBitsFromNum(pixel[j],bits) if ret == -1: return (ret,outputBits) outputBitsStream += outputBits output = getBytesFromBits(outputBitsStream) return output # PNG prediction # http://www.libpng.org/pub/png/spec/1.2/PNG-Filters.html # http://www.gnupdf.org/PNG_and_TIFF_Predictors_Filter#TIFF elif predictor >= 10 and predictor <= 15: bytesPerRow += 1 numRows = (len(decodedStream) + bytesPerRow -1) / bytesPerRow numSamplesPerRow = columns + 1 bytesPerSample = (colors * bits + 7) / 8 upRowdata = (0,) * numSamplesPerRow for row in xrange(numRows): rowdata = [ord(x) for x in decodedStream[(row*bytesPerRow):((row+1)*bytesPerRow)]] # PNG prediction can vary from row to row filterByte = rowdata[0] rowdata[0] = 0 if filterByte == 0: # None pass elif filterByte == 1: # Sub - 11 for i in range(1, numSamplesPerRow): if i < bytesPerSample: prevSample = 0 else: prevSample = rowdata[i-bytesPerSample] rowdata[i] = (rowdata[i] + prevSample) % 256 elif filterByte == 2: # Up - 12 for i in range(1, numSamplesPerRow): upSample = upRowdata[i] rowdata[i] = (rowdata[i] + upSample) % 256 elif filterByte == 3: # Average - 13 for i in range(1, numSamplesPerRow): upSample = upRowdata[i] if i < bytesPerSample: prevSample = 0 else: prevSample = rowdata[i-bytesPerSample] rowdata[i] = (rowdata[i] + ((prevSample+upSample)/2)) % 256 elif filterByte == 4: # Paeth - 14 for i in range(1, numSamplesPerRow): upSample = upRowdata[i] if i < bytesPerSample: prevSample = 0 upPrevSample = 0 else: prevSample = rowdata[i-bytesPerSample] upPrevSample = upRowdata[i-bytesPerSample] p = prevSample + upSample - upPrevSample pa = abs(p - prevSample) pb = abs(p - upSample) pc = abs(p - upPrevSample) if pa <= pb and pa <= pc: nearest = prevSample elif pb <= pc: nearest = upSample else: nearest = upPrevSample rowdata[i] = (rowdata[i] + nearest) % 256 else: # Optimum - 15 #return (-1,'Unsupported predictor') pass upRowdata = rowdata output += (''.join([chr(x) for x in rowdata[1:]])) return (0,output) else: return (-1,'Wrong value for predictor')