def file_reader(self):
        """Generator process to read file"""
        self.update_config()
        path = self.config['path']
        fourcc = self.metadata.get('fourcc')
        xlen, ylen = self.metadata.image_size()
        # set bits per pixel and component dimensions
        if fourcc in ('BGR[24]',):
            bpp = 24
            Y_shape = (ylen, xlen)
        elif fourcc in ('RGB[24]',):
            bpp = 24
            Y_shape = (ylen, xlen, 3)
        elif fourcc in ('IYU2',):
            bpp = 24
            Y_shape = (ylen, xlen, 1)
            UV_shape = (ylen, xlen)
        elif fourcc in ('UYVY', 'UYNV', 'Y422', 'HDYC', 'YVYU', 'YUYV',
                        'YV16', 'YUY2', 'YUNV', 'V422'):
            bpp = 16
            Y_shape = (ylen, xlen, 1)
            UV_shape = (ylen, xlen // 2)
        elif fourcc in ('IYUV', 'I420', 'YV12'):
            bpp = 12
            Y_shape = (ylen, xlen, 1)
            UV_shape = (ylen // 2, xlen // 2)
        elif fourcc in ('YVU9',):
            bpp = 9
            Y_shape = (ylen, xlen, 1)
            UV_shape = (ylen // 4, xlen // 4)
        else:
            self.logger.critical("Can't open %s files", fourcc)
            return
        bytes_per_frame = (xlen * ylen * bpp) // 8
        zlen = os.path.getsize(path) // bytes_per_frame
        if zlen < 1:
            self.logger.critical("Zero length file %s", path)
            return
        # set raw array slice parameters
        if fourcc in ('BGR[24]',):
            Y_slice = ((2, None, 3), (1, None, 3), (0, None, 3))
            UV_slice = None
        elif fourcc in ('RGB[24]',):
            Y_slice = ((0, None, 1),)
            UV_slice = None
        elif fourcc in ('IYU2',):
            Y_slice = ((1, None, 3),)
            UV_slice = ((0, None, 3), (2, None, 3))
        elif fourcc in ('UYVY', 'UYNV', 'Y422', 'HDYC'):
            # packed format, UYVY order
            Y_slice = ((1, None, 2),)
            UV_slice = ((0, None, 4), (2, None, 4))
        elif fourcc in ('YVYU',):
            # packed format, YVYU order
            Y_slice = ((0, None, 2),)
            UV_slice = ((3, None, 4), (1, None, 4))
        elif fourcc in ('YUYV', 'YUY2', 'YUNV', 'V422'):
            # packed format, YUYV order
            Y_slice = ((0, None, 2),)
            UV_slice = ((1, None, 4), (3, None, 4))
        elif fourcc in ('IYUV', 'I420'):
            # planar format, YUV order
            Y_size = xlen * ylen
            UV_size = UV_shape[0] * UV_shape[1]
            Y_slice = ((0,                Y_size,                 1),)
            UV_slice = ((Y_size,           Y_size + UV_size,       1),
                        (Y_size + UV_size, Y_size + (UV_size * 2), 1))
        elif fourcc in ('YV16', 'YV12', 'YVU9'):
            # planar format, YVU order
            Y_size = xlen * ylen
            UV_size = UV_shape[0] * UV_shape[1]
            Y_slice = ((0,                Y_size,                 1),)
            UV_slice = ((Y_size + UV_size, Y_size + (UV_size * 2), 1),
                        (Y_size,           Y_size + UV_size,       1))
        else:
            self.logger.critical("Can't open %s files", fourcc)
            return
        # set frame type
        if fourcc in ('BGR[24]', 'RGB[24]'):
            self.Y_type = 'RGB'
        else:
            self.Y_type = 'Y'
            self.UV_type = 'CbCr'
        file_frame = 0
        direction = 1
        with io.open(path, 'rb', 0) as raw_file:
            while True:
                self.update_config()
                if file_frame >= zlen:
                    if self.config['looping'] == 'off':
                        break
                    elif self.config['looping'] == 'repeat':
                        file_frame = 0
                        raw_file.seek(0)
                    else:
                        file_frame = zlen - 2
                        direction = -1
                elif file_frame < 0:
                    file_frame = 1
                    direction = 1
                if direction != 1:
                    raw_file.seek((direction - 1) * bytes_per_frame, io.SEEK_CUR)
                file_frame += direction
                raw_data = raw_file.read(bytes_per_frame)
                # convert to numpy arrays
                raw_array = numpy.frombuffer(raw_data, numpy.uint8)
                Y_data = []
                for start, end, step in Y_slice:
                    raw_data = raw_array[start:end:step]
                    Y_data.append(raw_data.reshape(Y_shape))
                if len(Y_data) > 1:
                    Y_data = numpy.dstack(Y_data)
                else:
                    Y_data = Y_data[0]
                if UV_slice:
                    UV_data = []
                    for start, end, step in UV_slice:
                        raw_data = raw_array[start:end:step]
                        UV_data.append(raw_data.reshape(UV_shape))
                    UV_data = numpy.dstack(UV_data)
                    # remove offset
                    UV_data = UV_data.astype(pt_float) - pt_float(128.0)
                else:
                    UV_data = None
                yield Y_data, UV_data