# Buggy code
def dec10216(inbuf):
    arr10 = inbuf.astype(np.uint16)
    arr16 = np.zeros((int(len(arr10) * 4 / 5),), dtype=np.uint16)
    arr10_len = int((len(arr16) * 5) / 4)
    arr10 = arr10[:arr10_len]  # adjust size
    """
    /*
     * pack 4 10-bit words in 5 bytes into 4 16-bit words
     *
     * 0       1       2       3       4       5
     * 01234567890123456789012345678901234567890
     * 0         1         2         3         4
     */
    ip = &in_buffer[i];
    op = &out_buffer[j];
    op[0] = ip[0]*4 + ip[1]/64;
    op[1] = (ip[1] & 0x3F)*16 + ip[2]/16;
    op[2] = (ip[2] & 0x0F)*64 + ip[3]/4;
    op[3] = (ip[3] & 0x03)*256 +ip[4];
    """
    arr16.flat[::4] = np.left_shift(arr10[::5], 2) + np.right_shift((arr10[1::5]), 6)
    arr16.flat[1::4] = np.left_shift((arr10[1::5] & 63), 4) + np.right_shift(
        (arr10[2::5]), 4
    )
    arr16.flat[2::4] = np.left_shift(arr10[2::5] & 15, 6) + np.right_shift(
        (arr10[3::5]), 2
    )
    arr16.flat[3::4] = np.left_shift(arr10[3::5] & 3, 8) + arr10[4::5]
    return arr16


# Traceback (AttributeError)
[INFO: 2017-12-12 08:14:04 : satpy.writers.cf_writer] Saving datasets to NetCDF4/CF.
[INFO: 2017-12-12 08:14:04 : satpy.writers.cf_writer] No longitude and latitude data to save.
[INFO: 2017-12-12 08:14:04 : satpy.writers.cf_writer] No grid mapping to save.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-24-58ece08c15f3> in <module>()
----> 1 lcl.save_datasets(writer='cf', filename='/tmp/foo.nc')

/home/lahtinep/Software/pytroll/packages/satpy/satpy/scene.pyc in save_datasets(self, writer, datasets, **kwargs)
632             datasets = self.datasets.values()
633         writer = self.get_writer(writer, **kwargs)
--> 634         writer.save_datasets(datasets, **kwargs)
635
636     def get_writer(self, writer="geotiff", **kwargs):

/home/lahtinep/Software/pytroll/packages/satpy/satpy/writers/cf_writer.pyc in save_datasets(self, datasets, filename, **kwargs)
176                     coords = [line_coord, pixel_coord]
177
--> 178                 domain = cf.Domain(dim=coords,
179                                    aux=aux,
180                                    ref=grid_mapping)

AttributeError: 'module' object has no attribute 'Domain'

# Fixed code
def dec10216(inbuf):
    """
    /*
     * pack 4 10-bit words in 5 bytes into 4 16-bit words
     *
     * 0       1       2       3       4       5
     * 01234567890123456789012345678901234567890
     * 0         1         2         3         4
     */
    ip = &in_buffer[i];
    op = &out_buffer[j];
    op[0] = ip[0]*4 + ip[1]/64;
    op[1] = (ip[1] & 0x3F)*16 + ip[2]/16;
    op[2] = (ip[2] & 0x0F)*64 + ip[3]/4;
    op[3] = (ip[3] & 0x03)*256 +ip[4];
    """

    arr10 = inbuf.astype(np.uint16)
    arr16_len = int(len(arr10) * 4 / 5)
    arr10_len = int((arr16_len * 5) / 4)
    arr10 = arr10[:arr10_len]  # adjust size

    # dask is slow with indexing
    arr10_0 = arr10[::5]
    arr10_1 = arr10[1::5]
    arr10_2 = arr10[2::5]
    arr10_3 = arr10[3::5]
    arr10_4 = arr10[4::5]

    arr16_0 = (arr10_0 << 2) + (arr10_1 >> 6)
    arr16_1 = ((arr10_1 & 63) << 4) + (arr10_2 >> 4)
    arr16_2 = ((arr10_2 & 15) << 6) + (arr10_3 >> 2)
    arr16_3 = ((arr10_3 & 3) << 8) + arr10_4
    arr16 = da.stack([arr16_0, arr16_1, arr16_2, arr16_3], axis=-1).ravel()

    return arr16