def upload_image(vol, img, offset, parallel=1, 
  manual_shared_memory_id=None, manual_shared_memory_bbox=None, manual_shared_memory_order='F'):
  """Upload img to vol with offset. This is the primary entry point for uploads."""
  global NON_ALIGNED_WRITE

  if not np.issubdtype(img.dtype, np.dtype(vol.dtype).type):
    raise ValueError('The uploaded image data type must match the volume data type. volume: {}, image: {}'.format(vol.dtype, img.dtype))

  (is_aligned, bounds, expanded) = check_grid_aligned(vol, img, offset)

  if is_aligned:
    upload_aligned(vol, img, offset, parallel=parallel, 
      manual_shared_memory_id=manual_shared_memory_id, manual_shared_memory_bbox=manual_shared_memory_bbox,
      manual_shared_memory_order=manual_shared_memory_order)
    return
  elif vol.non_aligned_writes == False:
    msg = NON_ALIGNED_WRITE.format(mip=vol.mip, chunk_size=vol.chunk_size, offset=vol.voxel_offset, got=bounds, check=expanded)
    raise AlignmentError(msg)

  # Upload the aligned core
  retracted = bounds.shrink_to_chunk_size(vol.underlying, vol.voxel_offset)
  core_bbox = retracted.clone() - bounds.minpt

  if not core_bbox.subvoxel():
    core_img = img[ core_bbox.to_slices() ] 
    upload_aligned(vol, core_img, retracted.minpt, parallel=parallel, 
      manual_shared_memory_id=manual_shared_memory_id, manual_shared_memory_bbox=manual_shared_memory_bbox,
      manual_shared_memory_order=manual_shared_memory_order)

  # Download the shell, paint, and upload
  all_chunks = set(chunknames(expanded, vol.bounds, vol.key, vol.underlying))
  core_chunks = set(chunknames(retracted, vol.bounds, vol.key, vol.underlying))
  shell_chunks = all_chunks.difference(core_chunks)

  def shade_and_upload(img3d, bbox):
    # decode is returning non-writable chunk
    # we're throwing them away so safe to write
    img3d.setflags(write=1) 
    shade(img3d, bbox, img, bounds)
    single_process_upload(vol, img3d, (( Vec(0,0,0), Vec(*img3d.shape[:3]), bbox.minpt, bbox.maxpt),), n_threads=0)

  download_multiple(vol, shell_chunks, fn=shade_and_upload)
Upload img to vol with offset. This is the primary entry point for uploads.