If you run pngcheck
on the image, it will tell you that the checksum of the IEND
chunk is incorrect:
pngcheck - v blank.png
Output
File: blank.png(79830 bytes)
chunk IHDR at offset 0x0000c, length 13
2560 x 1600 image, 32 - bit RGB + alpha, non - interlaced
chunk IDAT at offset 0x00025, length 8192
zlib: deflated, 32 K window, fast compression
chunk IDAT at offset 0x02031, length 8192
chunk IDAT at offset 0x0403d, length 8192
chunk IDAT at offset 0x06049, length 8192
chunk IDAT at offset 0x08055, length 8192
chunk IDAT at offset 0x0a061, length 8192
chunk IDAT at offset 0x0c06d, length 8192
chunk IDAT at offset 0x0e079, length 8192
chunk IDAT at offset 0x10085, length 8192
chunk IDAT at offset 0x12091, length 5937
chunk IEND at offset 0x137ce, length 0
CRC error in chunk IEND(computed ae426082, expected ae426080)
If you dump the file in hex:
xxd image.png > hex
December 26, 2016 at 6:56 pm,December 26, 2016 at 12:17 pm,December 27, 2016 at 3:04 pm,December 27, 2016 at 6:40 am
When using the Python programming language you’ll inevitably run into an error that looks like this:
AttributeError: 'NoneType'
object has no attribute‘ something’
Here is an example of generating a NoneType
error from the Python shell:
>>> foo = None
>>> foo.bar = True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'bar'
>>>
Here is an example of trying to load a nonexistent image from disk:
$ python
>>> import cv2
>>> path = "path/to/image/that/does/not/exist.png"
>>> image = cv2.imread(path)
>>> print(image.shape)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'shape'
Open up a new file, name it display_image.py
, and insert the following code:
# import the necessary packages import argparse import cv2 # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required = True, help = "path to the image file") args = vars(ap.parse_args()) # load the image from disk and display the width, height, # and depth image = cv2.imread(args["image"]) (h, w, d) = image.shape print("w: {}, h: {}, d: {}".format(w, h, d)) # show the image cv2.imshow("Image", image) cv2.waitKey(0)
Going back to the example, let’s check the contents of my local directory:
$ ls - l total 800 - rw - r--r--1 adrianrosebrock staff 541 Dec 21 08: 45 display_image.py - rw - r--r--1 adrianrosebrock staff 403494 Dec 21 08: 45 jemma.png
The concept of the CRC as an error-detecting code gets complicated when an implementer or standards committee uses it to design a practical system. Here are some of the complications: ,A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to digital data. Blocks of data entering these systems get a short check value attached, based on the remainder of a polynomial division of their contents. On retrieval, the calculation is repeated and, in the event the check values do not match, corrective action can be taken against data corruption. CRCs can be used for error correction (see bitfilters).[1] ,When a codeword is received or read, the device either compares its check value with one freshly calculated from the data block, or equivalently, performs a CRC on the whole codeword and compares the resulting check value with an expected residue constant. ,CRCs are specifically designed to protect against common types of errors on communication channels, where they can provide quick and reasonable assurance of the integrity of messages delivered. However, they are not suitable for protecting against intentional alteration of data.
def crc_remainder(input_bitstring, polynomial_bitstring, initial_filler): "" "Calculate the CRC remainder of a string of bits using a chosen polynomial. initial_filler should be '1' or '0'. "" " polynomial_bitstring = polynomial_bitstring.lstrip('0') len_input = len(input_bitstring) initial_padding = (len(polynomial_bitstring) - 1) * initial_filler input_padded_array = list(input_bitstring + initial_padding) while '1' in input_padded_array[: len_input]: cur_shift = input_padded_array.index('1') for i in range(len(polynomial_bitstring)): input_padded_array[cur_shift + i]\ = str(int(polynomial_bitstring[i] != input_padded_array[cur_shift + i])) return ''.join(input_padded_array)[len_input: ] def crc_check(input_bitstring, polynomial_bitstring, check_value): "" "Calculate the CRC check of a string of bits using a chosen polynomial." "" polynomial_bitstring = polynomial_bitstring.lstrip('0') len_input = len(input_bitstring) initial_padding = check_value input_padded_array = list(input_bitstring + initial_padding) while '1' in input_padded_array[: len_input]: cur_shift = input_padded_array.index('1') for i in range(len(polynomial_bitstring)): input_padded_array[cur_shift + i]\ = str(int(polynomial_bitstring[i] != input_padded_array[cur_shift + i])) return ('1' not in ''.join(input_padded_array)[len_input: ])
>>> crc_remainder('11010011101100', '1011', '0')
'100' >>>
crc_check('11010011101100', '1011', '100')
True
#include <inttypes.h> // uint32_t, uint8_t
uint32_t CRC32(const uint8_t data[], size_t data_length) {
uint32_t crc32 = 0xFFFFFFFFu;
for (size_t i = 0; i < data_length; i++) {
const uint32_t lookupIndex = (crc32 ^ data[i]) & 0xff;
crc32 = (crc32 >> 8) ^ CRCTable[lookupIndex]; // CRCTable is an array of 256 32-bit constants
}
// Finalize the CRC-32 value by inverting all the bits
crc32 ^= 0xFFFFFFFFu;
return crc32;
}