//  [python]
def draw(input_mode, input, refer_input_state, refer_text_show, imagebox_refer):
    if type(input) == dict:
        image = deepcopy(input['image'])
        mask = deepcopy(input['mask'])
    else:
        mask = deepcopy(input)

    # W, H -> H, W, 3
    image_new = np.asarray(image)
    img_height = image_new.shape[0]
    img_width = image_new.shape[1]

    # W, H, 4 -> H, W
    mask_new = np.asarray(mask)[:,:,0].copy()
    mask_new = torch.from_numpy(mask_new)
    mask_new = (F.interpolate(mask_new.unsqueeze(0).unsqueeze(0), (img_height, img_width), mode='bilinear') > 0)
    mask_new = mask_new[0, 0].transpose(1, 0).long()

    if len(refer_input_state['masks']) == 0:
        last_mask = torch.zeros_like(mask_new)
    else:
        last_mask = refer_input_state['masks'][-1]

    diff_mask = mask_new - last_mask
    if torch.all(diff_mask == 0):
        print('Init Uploading Images.')
        return (refer_input_state, refer_text_show, image)
    else:
        refer_input_state['masks'].append(mask_new)

    if input_mode == 'Point':
        nonzero_points = diff_mask.nonzero()
        nonzero_points_avg_x = torch.median(nonzero_points[:, 0])
        nonzero_points_avg_y = torch.median(nonzero_points[:, 1])
        sampled_coor = [nonzero_points_avg_x, nonzero_points_avg_y]
        # pdb.set_trace()
        cur_region_masks = generate_mask_for_feature(sampled_coor, raw_w=img_width, raw_h=img_height)
    elif input_mode == 'Box' or input_mode == 'Sketch':
        # pdb.set_trace()
        x1x2 = diff_mask.max(1)[0].nonzero()[:, 0]
        y1y2 = diff_mask.max(0)[0].nonzero()[:, 0]
        y1, y2 = y1y2.min(), y1y2.max()
        x1, x2 = x1x2.min(), x1x2.max()
        # pdb.set_trace()
        sampled_coor = [x1, y1, x2, y2]
        if input_mode == 'Box':
            cur_region_masks = generate_mask_for_feature(sampled_coor, raw_w=img_width, raw_h=img_height)
        else:
            cur_region_masks = generate_mask_for_feature(sampled_coor, raw_w=img_width, raw_h=img_height, mask=diff_mask)
    else:
        raise NotImplementedError(f'Input mode of {input_mode} is not Implemented.')

    # TODO(haoxuan): Hack img_size to be 224 here, need to make it a argument.
    if len(sampled_coor) == 2:
        point_x = int(VOCAB_IMAGE_W * sampled_coor[0] / img_width)
        point_y = int(VOCAB_IMAGE_H * sampled_coor[1] / img_height)
        cur_region_coordinates = f'[{int(point_x)}, {int(point_y)}]'
    elif len(sampled_coor) == 4:
        point_x1 = int(VOCAB_IMAGE_W * sampled_coor[0] / img_width)
        point_y1 = int(VOCAB_IMAGE_H * sampled_coor[1] / img_height)
        point_x2 = int(VOCAB_IMAGE_W * sampled_coor[2] / img_width)
        point_y2 = int(VOCAB_IMAGE_H * sampled_coor[3] / img_height)
        cur_region_coordinates = f'[{int(point_x1)}, {int(point_y1)}, {int(point_x2)}, {int(point_y2)}]'

    cur_region_id = len(refer_input_state['region_placeholder_tokens'])
    cur_region_token = DEFAULT_REGION_REFER_TOKEN.split(']')[0] + str(cur_region_id) + ']'
    refer_input_state['region_placeholder_tokens'].append(cur_region_token)
    refer_input_state['region_coordinates'].append(cur_region_coordinates)
    refer_input_state['region_masks'].append(cur_region_masks)
    assert len(refer_input_state['region_masks']) == len(refer_input_state['region_coordinates']) == len(refer_input_state['region_placeholder_tokens'])
    refer_text_show.append((cur_region_token, ''))

    # Show Parsed Referring.
    imagebox_refer = draw_box(sampled_coor, cur_region_masks, \
                         cur_region_token, imagebox_refer, input_mode)

    return (refer_input_state, refer_text_show, imagebox_refer)