diff --git a/skimage/io/_plugins/fits_plugin.py b/skimage/io/_plugins/fits_plugin.py index cf714ea6..f59f8707 100644 --- a/skimage/io/_plugins/fits_plugin.py +++ b/skimage/io/_plugins/fits_plugin.py @@ -8,7 +8,8 @@ except ImportError: try: import pyfits except ImportError: - raise ImportError("PyFITS could not be found. Please refer to\n" + raise ImportError( + "PyFITS could not be found. Please refer to\n" "http://www.stsci.edu/resources/software_hardware/pyfits\n" "for further instructions.") @@ -144,7 +145,7 @@ def FITSFactory(image_ext): hdulist.close() if data is None: - raise RuntimeError("Extension %d of %s has no data" % - (extnum, filename)) + raise RuntimeError( + "Extension %d of %s has no data" % (extnum, filename)) return data diff --git a/skimage/io/_plugins/freeimage_plugin.py b/skimage/io/_plugins/freeimage_plugin.py index 79c97641..a74c141f 100644 --- a/skimage/io/_plugins/freeimage_plugin.py +++ b/skimage/io/_plugins/freeimage_plugin.py @@ -28,8 +28,8 @@ def _generate_candidate_libs(): for lib_name in lib_names: files = os.listdir(lib_dir) lib_paths += [os.path.join(lib_dir, lib) for lib in files - if lib.lower().startswith(lib_name) and not - os.path.splitext(lib)[1] in ('.py', '.pyc', '.ini')] + if lib.lower().startswith(lib_name) and not + os.path.splitext(lib)[1] in ('.py', '.pyc', '.ini')] lib_paths = [lp for lp in lib_paths if os.path.exists(lp)] return lib_dirs, lib_paths @@ -41,6 +41,7 @@ else: LOADER = ctypes.cdll FUNCTYPE = ctypes.CFUNCTYPE + def handle_errors(): global FT_ERROR_STR if FT_ERROR_STR: @@ -48,7 +49,10 @@ def handle_errors(): FT_ERROR_STR = None raise RuntimeError(tmp) + FT_ERROR_STR = None + + # This MUST happen in module scope, or the function pointer is garbage # collected, leading to a segfault when error_handler is called. @FUNCTYPE(None, ctypes.c_int, ctypes.c_char_p) @@ -56,6 +60,7 @@ def c_error_handler(fif, message): global FT_ERROR_STR FT_ERROR_STR = 'FreeImage error: %s' % message + def load_freeimage(): freeimage = None errors = [] @@ -63,7 +68,7 @@ def load_freeimage(): # in the default locations for each platform. Win DLL names don't need the # extension, but other platforms do. bare_libs = ['FreeImage', 'libfreeimage.dylib', 'libfreeimage.so', - 'libfreeimage.so.3'] + 'libfreeimage.so.3'] lib_dirs, lib_paths = _generate_candidate_libs() lib_paths = bare_libs + lib_paths for lib in lib_paths: @@ -86,13 +91,13 @@ def load_freeimage(): # No freeimage library loaded, and load-errors reported for some # candidate libs err_txt = ['%s:\n%s' % (l, str(e)) for l, e in errors] - raise RuntimeError('One or more FreeImage libraries were found, but ' - 'could not be loaded due to the following errors:\n' - '\n\n'.join(err_txt)) + raise RuntimeError('One or more FreeImage libraries were found, ' + 'but could not be loaded due to the following ' + 'errors:\n\n\n'.join(err_txt)) else: # No errors, because no potential libraries found at all! - raise RuntimeError('Could not find a FreeImage library in any of:\n' + - '\n'.join(lib_dirs)) + raise RuntimeError('Could not find a FreeImage library in any of:' + '\n\n'.join(lib_dirs)) # FreeImage found freeimage.FreeImage_SetOutputMessage(c_error_handler) @@ -121,7 +126,7 @@ API = { 'FreeImage_Load': (ctypes.c_void_p, None), 'FreeImage_LockPage': (ctypes.c_void_p, None), 'FreeImage_OpenMultiBitmap': (ctypes.c_void_p, None) - } +} # Albert's ctypes pattern @@ -135,7 +140,7 @@ def register_api(lib, api): register_api(_FI, API) -class FI_TYPES(object): +class FiTypes(object): FIT_UNKNOWN = 0 FIT_BITMAP = 1 FIT_UINT16 = 2 @@ -150,51 +155,48 @@ class FI_TYPES(object): FIT_RGBF = 11 FIT_RGBAF = 12 - dtypes = { - FIT_BITMAP: numpy.uint8, - FIT_UINT16: numpy.uint16, - FIT_INT16: numpy.int16, - FIT_UINT32: numpy.uint32, - FIT_INT32: numpy.int32, - FIT_FLOAT: numpy.float32, - FIT_DOUBLE: numpy.float64, - FIT_COMPLEX: numpy.complex128, - FIT_RGB16: numpy.uint16, - FIT_RGBA16: numpy.uint16, - FIT_RGBF: numpy.float32, - FIT_RGBAF: numpy.float32 - } + dtypes = {FIT_BITMAP: numpy.uint8, + FIT_UINT16: numpy.uint16, + FIT_INT16: numpy.int16, + FIT_UINT32: numpy.uint32, + FIT_INT32: numpy.int32, + FIT_FLOAT: numpy.float32, + FIT_DOUBLE: numpy.float64, + FIT_COMPLEX: numpy.complex128, + FIT_RGB16: numpy.uint16, + FIT_RGBA16: numpy.uint16, + FIT_RGBF: numpy.float32, + FIT_RGBAF: numpy.float32, + } - fi_types = { - (numpy.dtype('uint8'), 1): FIT_BITMAP, - (numpy.dtype('uint8'), 3): FIT_BITMAP, - (numpy.dtype('uint8'), 4): FIT_BITMAP, - (numpy.dtype('uint16'), 1): FIT_UINT16, - (numpy.dtype('int16'), 1): FIT_INT16, - (numpy.dtype('uint32'), 1): FIT_UINT32, - (numpy.dtype('int32'), 1): FIT_INT32, - (numpy.dtype('float32'), 1): FIT_FLOAT, - (numpy.dtype('float64'), 1): FIT_DOUBLE, - (numpy.dtype('complex128'), 1): FIT_COMPLEX, - (numpy.dtype('uint16'), 3): FIT_RGB16, - (numpy.dtype('uint16'), 4): FIT_RGBA16, - (numpy.dtype('float32'), 3): FIT_RGBF, - (numpy.dtype('float32'), 4): FIT_RGBAF - } + fi_types = {(numpy.dtype('uint8'), 1): FIT_BITMAP, + (numpy.dtype('uint8'), 3): FIT_BITMAP, + (numpy.dtype('uint8'), 4): FIT_BITMAP, + (numpy.dtype('uint16'), 1): FIT_UINT16, + (numpy.dtype('int16'), 1): FIT_INT16, + (numpy.dtype('uint32'), 1): FIT_UINT32, + (numpy.dtype('int32'), 1): FIT_INT32, + (numpy.dtype('float32'), 1): FIT_FLOAT, + (numpy.dtype('float64'), 1): FIT_DOUBLE, + (numpy.dtype('complex128'), 1): FIT_COMPLEX, + (numpy.dtype('uint16'), 3): FIT_RGB16, + (numpy.dtype('uint16'), 4): FIT_RGBA16, + (numpy.dtype('float32'), 3): FIT_RGBF, + (numpy.dtype('float32'), 4): FIT_RGBAF, + } - extra_dims = { - FIT_UINT16: [], - FIT_INT16: [], - FIT_UINT32: [], - FIT_INT32: [], - FIT_FLOAT: [], - FIT_DOUBLE: [], - FIT_COMPLEX: [], - FIT_RGB16: [3], - FIT_RGBA16: [4], - FIT_RGBF: [3], - FIT_RGBAF: [4] - } + extra_dims = {FIT_UINT16: [], + FIT_INT16: [], + FIT_UINT32: [], + FIT_INT32: [], + FIT_FLOAT: [], + FIT_DOUBLE: [], + FIT_COMPLEX: [], + FIT_RGB16: [3], + FIT_RGBA16: [4], + FIT_RGBF: [3], + FIT_RGBAF: [4], + } @classmethod def get_type_and_shape(cls, bitmap): @@ -223,62 +225,79 @@ class FI_TYPES(object): return numpy.dtype(dtype), extra_dims + [w, h] -class IO_FLAGS(object): - FIF_LOAD_NOPIXELS = 0x8000 # loading: load the image header only - # (not supported by all plugins) +class IoFlags(object): + # loading: load the image header only (not supported by all plugins) + FIF_LOAD_NOPIXELS = 0x8000 BMP_DEFAULT = 0 BMP_SAVE_RLE = 1 CUT_DEFAULT = 0 DDS_DEFAULT = 0 EXR_DEFAULT = 0 # save data as half with piz-based wavelet compression - EXR_FLOAT = 0x0001 # save data as float instead of as half (not recommended) + EXR_FLOAT = 0x0001 # save data as float instead of half (not recommended) EXR_NONE = 0x0002 # save with no compression EXR_ZIP = 0x0004 # save with zlib compression, in blocks of 16 scan lines EXR_PIZ = 0x0008 # save with piz-based wavelet compression EXR_PXR24 = 0x0010 # save with lossy 24-bit float compression - EXR_B44 = 0x0020 # save with lossy 44% float compression - # - goes to 22% when combined with EXR_LC - EXR_LC = 0x0040 # save images with one luminance and two chroma channels, - # rather than as RGB (lossy compression) + + # save with lossy 44% float compression (22% when combined with EXR_LC) + EXR_B44 = 0x0020 + + # one luminance and two chroma channels rather than as RGB (lossy) + EXR_LC = 0x0040 FAXG3_DEFAULT = 0 GIF_DEFAULT = 0 - GIF_LOAD256 = 1 # Load the image as a 256 color image with ununsed - # palette entries, if it's 16 or 2 color - GIF_PLAYBACK = 2 # 'Play' the GIF to generate each frame (as 32bpp) - # instead of returning raw frame data when loading + + # Load as 256 color image with ununsed palette entries if 16 or 2 color + GIF_LOAD256 = 1 + + # 'Play' the GIF generating each frame (as 32bpp) instead of raw frame data + GIF_PLAYBACK = 2 HDR_DEFAULT = 0 ICO_DEFAULT = 0 - ICO_MAKEALPHA = 1 # convert to 32bpp and create an alpha channel from the - # AND-mask when loading + + # convert to 32bpp then add an alpha channel from the AND-mask when loading + ICO_MAKEALPHA = 1 IFF_DEFAULT = 0 J2K_DEFAULT = 0 # save with a 16:1 rate JP2_DEFAULT = 0 # save with a 16:1 rate - JPEG_DEFAULT = 0 # loading (see JPEG_FAST); - # saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420) - JPEG_FAST = 0x0001 # load the file as fast as possible, - # sacrificing some quality - JPEG_ACCURATE = 0x0002 # load the file with the best quality, - # sacrificing some speed - JPEG_CMYK = 0x0004 # load separated CMYK "as is" - # (use | to combine with other load flags) - JPEG_EXIFROTATE = 0x0008 # load and rotate according to - # Exif 'Orientation' tag if available + + # loading (see JPEG_FAST) + # saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420) + JPEG_DEFAULT = 0 + + # load the file as fast as possible, sacrificing some quality + JPEG_FAST = 0x0001 + + # load the file with the best quality, sacrificing some speed + JPEG_ACCURATE = 0x0002 + + # load separated CMYK "as is" (use | to combine with other load flags) + JPEG_CMYK = 0x0004 + + # load and rotate according to Exif 'Orientation' tag if available + JPEG_EXIFROTATE = 0x0008 JPEG_QUALITYSUPERB = 0x80 # save with superb quality (100:1) JPEG_QUALITYGOOD = 0x0100 # save with good quality (75:1) JPEG_QUALITYNORMAL = 0x0200 # save with normal quality (50:1) JPEG_QUALITYAVERAGE = 0x0400 # save with average quality (25:1) JPEG_QUALITYBAD = 0x0800 # save with bad quality (10:1) - JPEG_PROGRESSIVE = 0x2000 # save as a progressive-JPEG - # (use | to combine with other save flags) - JPEG_SUBSAMPLING_411 = 0x1000 # save with high 4x1 chroma - # subsampling (4:1:1) - JPEG_SUBSAMPLING_420 = 0x4000 # save with medium 2x2 medium chroma - # subsampling (4:2:0) - default value - JPEG_SUBSAMPLING_422 = 0x8000 # save with low 2x1 chroma subsampling (4:2:2) + + # save as a progressive-JPEG (use | to combine with other save flags) + JPEG_PROGRESSIVE = 0x2000 + + # save with high 4x1 chroma subsampling (4:1:1) + JPEG_SUBSAMPLING_411 = 0x1000 + + # save with medium 2x2 medium chroma subsampling (4:2:0) - default value + JPEG_SUBSAMPLING_420 = 0x4000 + + # save with low 2x1 chroma subsampling (4:2:2) + JPEG_SUBSAMPLING_422 = 0x8000 JPEG_SUBSAMPLING_444 = 0x10000 # save with no chroma subsampling (4:4:4) - JPEG_OPTIMIZE = 0x20000 # on saving, compute optimal Huffman coding tables - # (can reduce a few percent of file size) + + # compute optimal Huffman coding tables (can reduce file size a few %) + JPEG_OPTIMIZE = 0x20000 # on saving, JPEG_BASELINE = 0x40000 # save basic JPEG, without metadata or any markers KOALA_DEFAULT = 0 LBM_DEFAULT = 0 @@ -292,33 +311,40 @@ class IO_FLAGS(object): PICT_DEFAULT = 0 PNG_DEFAULT = 0 PNG_IGNOREGAMMA = 1 # loading: avoid gamma correction - PNG_Z_BEST_SPEED = 0x0001 # save using ZLib level 1 compression flag - # (default value is 6) - PNG_Z_DEFAULT_COMPRESSION = 0x0006 # save using ZLib level 6 compression - # flag (default recommended value) - PNG_Z_BEST_COMPRESSION = 0x0009 # save using ZLib level 9 compression flag - # (default value is 6) + + # save using ZLib level 1 compression flag (default value is 6) + PNG_Z_BEST_SPEED = 0x0001 + + # save using ZLib level 6 compression flag (default recommended value) + PNG_Z_DEFAULT_COMPRESSION = 0x0006 + + # save using ZLib level 9 compression flag (default value is 6) + PNG_Z_BEST_COMPRESSION = 0x0009 PNG_Z_NO_COMPRESSION = 0x0100 # save without ZLib compression - PNG_INTERLACED = 0x0200 # save using Adam7 interlacing (use | to combine - # with other save flags) + + # save using Adam7 interlacing (use | to combine with other save flags) + PNG_INTERLACED = 0x0200 PNM_DEFAULT = 0 PNM_SAVE_RAW = 0 # Writer saves in RAW format (i.e. P4, P5 or P6) PNM_SAVE_ASCII = 1 # Writer saves in ASCII format (i.e. P1, P2 or P3) PSD_DEFAULT = 0 - PSD_CMYK = 1 # reads tags for separated CMYK (default is conversion to RGB) + PSD_CMYK = 1 # reads tags for separated CMYK (default converts to RGB) PSD_LAB = 2 # reads tags for CIELab (default is conversion to RGB) RAS_DEFAULT = 0 RAW_DEFAULT = 0 # load the file as linear RGB 48-bit - RAW_PREVIEW = 1 # try to load the embedded JPEG preview with included - # Exif Data or default to RGB 24-bit + + # try to load embedded JPEG preview from Exif Data or default to RGB 24-bit + RAW_PREVIEW = 1 RAW_DISPLAY = 2 # load the file as RGB 24-bit SGI_DEFAULT = 0 TARGA_DEFAULT = 0 TARGA_LOAD_RGB888 = 1 # Convert RGB555 and ARGB8888 -> RGB888. TARGA_SAVE_RLE = 2 # Save with RLE compression TIFF_DEFAULT = 0 - TIFF_CMYK = 0x0001 # reads/stores tags for separated CMYK - # (use | to combine with compression flags) + + # reads/stores tags for separated CMYK + # (use | to combine with compression flags) + TIFF_CMYK = 0x0001 TIFF_PACKBITS = 0x0100 # save using PACKBITS compression TIFF_DEFLATE = 0x0200 # save using DEFLATE (a.k.a. ZLIB) compression TIFF_ADOBE_DEFLATE = 0x0400 # save using ADOBE DEFLATE compression @@ -333,7 +359,7 @@ class IO_FLAGS(object): XPM_DEFAULT = 0 -class METADATA_MODELS(object): +class MetadataModels(object): FIMD_COMMENTS = 0 FIMD_EXIF_MAIN = 1 FIMD_EXIF_EXIF = 2 @@ -346,7 +372,7 @@ class METADATA_MODELS(object): FIMD_ANIMATION = 9 -class METADATA_DATATYPE(object): +class MetadataDatatype(object): FIDT_BYTE = 1 # 8-bit unsigned integer FIDT_ASCII = 2 # 8-bit bytes w/ last byte null FIDT_SHORT = 3 # 16-bit unsigned integer @@ -365,27 +391,26 @@ class METADATA_DATATYPE(object): FIDT_SLONG8 = 17 # 64-bit signed integer FIDT_IFD8 = 18 # 64-bit unsigned integer (offset) - dtypes = { - FIDT_BYTE: numpy.uint8, - FIDT_SHORT: numpy.uint16, - FIDT_LONG: numpy.uint32, - FIDT_RATIONAL: [('numerator', numpy.uint32), - ('denominator', numpy.uint32)], - FIDT_SBYTE: numpy.int8, - FIDT_UNDEFINED: numpy.uint8, - FIDT_SSHORT: numpy.int16, - FIDT_SLONG: numpy.int32, - FIDT_SRATIONAL: [('numerator', numpy.int32), - ('denominator', numpy.int32)], - FIDT_FLOAT: numpy.float32, - FIDT_DOUBLE: numpy.float64, - FIDT_IFD: numpy.uint32, - FIDT_PALETTE: [('R', numpy.uint8), ('G', numpy.uint8), - ('B', numpy.uint8), ('A', numpy.uint8)], - FIDT_LONG8: numpy.uint64, - FIDT_SLONG8: numpy.int64, - FIDT_IFD8: numpy.uint64 - } + dtypes = {FIDT_BYTE: numpy.uint8, + FIDT_SHORT: numpy.uint16, + FIDT_LONG: numpy.uint32, + FIDT_RATIONAL: [('numerator', numpy.uint32), + ('denominator', numpy.uint32)], + FIDT_SBYTE: numpy.int8, + FIDT_UNDEFINED: numpy.uint8, + FIDT_SSHORT: numpy.int16, + FIDT_SLONG: numpy.int32, + FIDT_SRATIONAL: [('numerator', numpy.int32), + ('denominator', numpy.int32)], + FIDT_FLOAT: numpy.float32, + FIDT_DOUBLE: numpy.float64, + FIDT_IFD: numpy.uint32, + FIDT_PALETTE: [('R', numpy.uint8), ('G', numpy.uint8), + ('B', numpy.uint8), ('A', numpy.uint8)], + FIDT_LONG8: numpy.uint64, + FIDT_SLONG8: numpy.int64, + FIDT_IFD8: numpy.uint64, + } def _process_bitmap(filename, flags, process_func): @@ -410,7 +435,7 @@ def read(filename, flags=0): """Read an image to a numpy array of shape (height, width) for greyscale images, or shape (height, width, nchannels) for RGB or RGBA images. - The `flags` parameter should be one or more values from the IO_FLAGS + The `flags` parameter should be one or more values from the IoFlags class defined in this module, or-ed together with | as appropriate. (See the source-code comments for more details.) """ @@ -422,9 +447,9 @@ def read_metadata(filename): Returned dict maps (metadata_model, tag_name) keys to tag values, where metadata_model is a string name based on the FreeImage "metadata models" - defined in the class METADATA_MODELS. + defined in the class MetadataModels. """ - flags = IO_FLAGS.FIF_LOAD_NOPIXELS + flags = IoFlags.FIF_LOAD_NOPIXELS return _process_bitmap(filename, flags, _read_metadata) @@ -437,9 +462,8 @@ def _process_multipage(filename, flags, process_func): create_new = False read_only = True keep_cache_in_memory = True - multibitmap = _FI.FreeImage_OpenMultiBitmap(ftype, filename, create_new, - read_only, keep_cache_in_memory, - flags) + multibitmap = _FI.FreeImage_OpenMultiBitmap( + ftype, filename, create_new, read_only, keep_cache_in_memory, flags) handle_errors() multibitmap = ctypes.c_void_p(multibitmap) if not multibitmap: @@ -454,7 +478,7 @@ def _process_multipage(filename, flags, process_func): bitmap = ctypes.c_void_p(bitmap) if not bitmap: raise ValueError('Could not open %s as a multi-page image.' - % filename) + % filename) try: out.append(process_func(bitmap)) finally: @@ -470,7 +494,7 @@ def read_multipage(filename, flags=0): """Read a multipage image to a list of numpy arrays, where each array is of shape (height, width) for greyscale images, or shape (height, width, nchannels) for RGB or RGBA images. - The `flags` parameter should be one or more values from the IO_FLAGS + The `flags` parameter should be one or more values from the IoFlags class defined in this module, or-ed together with | as appropriate. (See the source-code comments for more details.) """ @@ -481,7 +505,7 @@ def read_multipage_metadata(filename): """Read a multipage image to a list of metadata dicts, one dict for each page. The dict format is as in read_metadata(). """ - flags = IO_FLAGS.FIF_LOAD_NOPIXELS + flags = IoFlags.FIF_LOAD_NOPIXELS return _process_multipage(filename, flags, _read_metadata) @@ -503,9 +527,9 @@ def _wrap_bitmap_bits_in_array(bitmap, shape, dtype): strides = (itemsize, pitch) bits = _FI.FreeImage_GetBits(bitmap) handle_errors() - array = numpy.ndarray(shape, dtype=dtype, - buffer=(ctypes.c_char * byte_size).from_address(bits), - strides=strides) + array = numpy.ndarray( + shape, dtype=dtype, + buffer=(ctypes.c_char * byte_size).from_address(bits), strides=strides) return array @@ -513,8 +537,9 @@ def _array_from_bitmap(bitmap): """Convert a FreeImage bitmap pointer to a numpy array. """ - dtype, shape = FI_TYPES.get_type_and_shape(bitmap) + dtype, shape = FiTypes.get_type_and_shape(bitmap) array = _wrap_bitmap_bits_in_array(bitmap, shape, dtype) + # swizzle the color components and flip the scanlines to go from # FreeImage's BGR[A] and upside-down internal memory format to something # more normal @@ -542,7 +567,7 @@ def _array_from_bitmap(bitmap): def _read_metadata(bitmap): metadata = {} models = [(name[5:], number) for name, number in - METADATA_MODELS.__dict__.items() if name.startswith('FIMD_')] + MetadataModels.__dict__.items() if name.startswith('FIMD_')] tag = ctypes.c_void_p() for model_name, number in models: @@ -560,15 +585,16 @@ def _read_metadata(bitmap): char_ptr = ctypes.c_char * byte_size tag_str = char_ptr.from_address(_FI.FreeImage_GetTagValue(tag)) handle_errors() - if tag_type == METADATA_DATATYPE.FIDT_ASCII: + if tag_type == MetadataDatatype.FIDT_ASCII: tag_val = asstr(tag_str.value) else: - tag_val = numpy.fromstring(tag_str, - dtype=METADATA_DATATYPE.dtypes[tag_type]) + tag_val = numpy.fromstring( + tag_str, dtype=MetadataDatatype.dtypes[tag_type]) if len(tag_val) == 1: tag_val = tag_val[0] metadata[(model_name, tag_name)] = tag_val - more = _FI.FreeImage_FindNextMetadata(mdhandle, ctypes.byref(tag)) + more = _FI.FreeImage_FindNextMetadata(mdhandle, + ctypes.byref(tag)) handle_errors() _FI.FreeImage_FindCloseMetadata(mdhandle) handle_errors() @@ -579,7 +605,7 @@ def write(array, filename, flags=0): """Write a (height, width) or (height, width, nchannels) array to a greyscale, RGB, or RGBA image, with file type deduced from the filename. - The `flags` parameter should be one or more values from the IO_FLAGS + The `flags` parameter should be one or more values from the IoFlags class defined in this module, or-ed together with | as appropriate. (See the source-code comments for more details.) """ @@ -591,9 +617,9 @@ def write(array, filename, flags=0): raise ValueError('Cannot determine type for %s' % filename) bitmap, fi_type = _array_to_bitmap(array) try: - if fi_type == FI_TYPES.FIT_BITMAP: - can_write = _FI.FreeImage_FIFSupportsExportBPP(ftype, - _FI.FreeImage_GetBPP(bitmap)) + if fi_type == FiTypes.FIT_BITMAP: + can_write = _FI.FreeImage_FIFSupportsExportBPP( + ftype, _FI.FreeImage_GetBPP(bitmap)) handle_errors() else: can_write = _FI.FreeImage_FIFSupportsExportType(ftype, fi_type) @@ -614,7 +640,7 @@ def write_multipage(arrays, filename, flags=0): """Write a list of (height, width) or (height, width, nchannels) arrays to a multipage greyscale, RGB, or RGBA image, with file type deduced from the filename. - The `flags` parameter should be one or more values from the IO_FLAGS + The `flags` parameter should be one or more values from the IoFlags class defined in this module, or-ed together with | as appropriate. (See the source-code comments for more details.) """ @@ -660,7 +686,7 @@ def _array_to_bitmap(array): else: n_channels = shape[0] try: - fi_type = FI_TYPES.fi_types[(dtype, n_channels)] + fi_type = FiTypes.fi_types[(dtype, n_channels)] except KeyError: raise ValueError('Cannot write arrays of given type and shape.') @@ -678,22 +704,22 @@ def _array_to_bitmap(array): # swizzle the color components and flip the scanlines to go to # FreeImage's BGR[A] and upside-down internal memory format if len(shape) == 3 and _FI.FreeImage_IsLittleEndian(): - R = array[:, :, 0] - G = array[:, :, 1] - B = array[:, :, 2] + r = array[:, :, 0] + g = array[:, :, 1] + b = array[:, :, 2] if dtype.type == numpy.uint8: - wrapped_array[0] = n(B) - wrapped_array[1] = n(G) - wrapped_array[2] = n(R) + wrapped_array[0] = n(b) + wrapped_array[1] = n(g) + wrapped_array[2] = n(r) elif dtype.type == numpy.uint16: - wrapped_array[0] = n(R) - wrapped_array[1] = n(G) - wrapped_array[2] = n(B) + wrapped_array[0] = n(r) + wrapped_array[1] = n(g) + wrapped_array[2] = n(b) if shape[2] == 4: - A = array[:, :, 3] - wrapped_array[3] = n(A) + a = array[:, :, 3] + wrapped_array[3] = n(a) else: wrapped_array[:] = n(array) if len(shape) == 2 and dtype.type == numpy.uint8: diff --git a/skimage/io/_plugins/imread_plugin.py b/skimage/io/_plugins/imread_plugin.py index 9311f18f..3f63100a 100644 --- a/skimage/io/_plugins/imread_plugin.py +++ b/skimage/io/_plugins/imread_plugin.py @@ -9,6 +9,7 @@ except ImportError: "Please refer to http://pypi.python.org/pypi/imread/ " "for further instructions.") + def imread(fname, dtype=None): """Load an image from file. @@ -23,6 +24,7 @@ def imread(fname, dtype=None): im = convert(im, dtype) return im + def imsave(fname, arr, format_str=None): """Save an image to disk. @@ -40,4 +42,3 @@ def imsave(fname, arr, format_str=None): Currently, only 8-bit precision is supported. """ return _imread.imsave(fname, arr, formatstr=format_str) - diff --git a/skimage/io/_plugins/pil_plugin.py b/skimage/io/_plugins/pil_plugin.py index 4e830438..bb013b0b 100644 --- a/skimage/io/_plugins/pil_plugin.py +++ b/skimage/io/_plugins/pil_plugin.py @@ -26,8 +26,8 @@ def imread(fname, dtype=None, img_num=None, **kwargs): Notes ----- - Tiff files are handled by Christophe Golhke's tifffile.py [1]_, and support many - advanced image types including multi-page and floating point. + Tiff files are handled by Christophe Golhke's tifffile.py [1]_, and support + many advanced image types including multi-page and floating point. All other files are read using the Python Imaging Libary. See PIL docs [2]_ for a list of supported formats. @@ -67,9 +67,9 @@ def pil_to_ndarray(im, dtype=None, img_num=None): site = "http://pillow.readthedocs.org/en/latest/installation.html#external-libraries" pillow_error_message = str(e) error_message = ('Could not load "%s" \n' - 'Reason: "%s"\n' - 'Please see documentation at: %s' - % (im.filename, pillow_error_message, site)) + 'Reason: "%s"\n' + 'Please see documentation at: %s' + % (im.filename, pillow_error_message, site)) raise ValueError(error_message) frames = [] grayscale = None @@ -255,7 +255,7 @@ def imsave(fname, arr, format_str=None, **kwargs): and fname.lower().endswith(".png")): format_str = "PNG" - arr = np.asanyarray(arr).squeeze() + arr = np.asanyarray(arr) if arr.dtype.kind == 'b': arr = arr.astype(np.uint8) @@ -264,7 +264,7 @@ def imsave(fname, arr, format_str=None, **kwargs): if hasattr(fname, 'lower'): if fname.lower().endswith(('.tiff', '.tif')): use_tif = True - if not format_str is None: + if format_str is not None: if format_str.lower() in ['tiff', 'tif']: use_tif = True diff --git a/skimage/io/_plugins/qt_plugin.py b/skimage/io/_plugins/qt_plugin.py index f3a3b8e0..4d061933 100644 --- a/skimage/io/_plugins/qt_plugin.py +++ b/skimage/io/_plugins/qt_plugin.py @@ -94,23 +94,23 @@ def imread_qt(filename): arrayptr = qtimg.bits() # QT may pad the image, so we need to use bytesPerLine, not width for # the conversion to a numpy array - bytesPerPixel = qtimg.depth() // 8 - pixelsPerLine = qtimg.bytesPerLine() // bytesPerPixel - img_size = pixelsPerLine * qtimg.height() * bytesPerPixel + bytes_per_pixel = qtimg.depth() // 8 + pixels_per_line = qtimg.bytesPerLine() // bytes_per_pixel + img_size = pixels_per_line * qtimg.height() * bytes_per_pixel arrayptr.setsize(img_size) img = np.array(arrayptr) # Reshape and trim down to correct dimensions - if bytesPerPixel > 1: - img = img.reshape((qtimg.height(), pixelsPerLine, bytesPerPixel)) + if bytes_per_pixel > 1: + img = img.reshape((qtimg.height(), pixels_per_line, bytes_per_pixel)) img = img[:, :qtimg.width(), :] else: - img = img.reshape((qtimg.height(), pixelsPerLine)) + img = img.reshape((qtimg.height(), pixels_per_line)) img = img[:, :qtimg.width()] # Strip qt's false alpha channel if needed # and reorder color axes as required - if bytesPerPixel == 4 and not qtimg.hasAlphaChannel(): + if bytes_per_pixel == 4 and not qtimg.hasAlphaChannel(): img = img[:, :, 2::-1] - elif bytesPerPixel == 4: + elif bytes_per_pixel == 4: img[:, :, 0:3] = img[:, :, 2::-1] return img @@ -151,7 +151,7 @@ def imsave(filename, img, format_str=None): # we can add support for other than 3D uint8 here... img = prepare_for_display(img) qimg = QImage(img.data, img.shape[1], img.shape[0], - img.strides[0], QImage.Format_RGB888) + img.strides[0], QImage.Format_RGB888) if _is_filelike(filename): byte_array = QtCore.QByteArray() qbuffer = QtCore.QBuffer(byte_array) diff --git a/skimage/io/_plugins/tifffile_plugin.py b/skimage/io/_plugins/tifffile_plugin.py index 3ae90449..817776c2 100644 --- a/skimage/io/_plugins/tifffile_plugin.py +++ b/skimage/io/_plugins/tifffile_plugin.py @@ -11,7 +11,8 @@ def imread(fname, dtype=None, **kwargs): dtype : numpy dtype object or string specifier Specifies data type of array elements (Not currently used). kwargs : keyword pairs, optional - Addition keyword arguments to pass through (see `tifffile`'s `imread` function). + Additional keyword arguments to pass through (see ``tifffile``'s + ``imread`` function). Notes -----