+ sub->rects[i] = av_mallocz(sizeof(*sub->rects[0]));
+ if (!sub->rects[i]) {
+ avsubtitle_free(sub);
+ return AVERROR(ENOMEM);
+ }
+ sub->num_rects++;
+ sub->rects[i]->type = SUBTITLE_BITMAP;
+
+ /* Process bitmap */
+ object = find_object(ctx->presentation.objects[i].id, &ctx->objects);
+ if (!object) {
+ // Missing object. Should only happen with damaged streams.
+ av_log(avctx, AV_LOG_ERROR, "Invalid object id %d\n",
+ ctx->presentation.objects[i].id);
+ if (avctx->err_recognition & AV_EF_EXPLODE) {
+ avsubtitle_free(sub);
+ return AVERROR_INVALIDDATA;
+ }
+ // Leaves rect empty with 0 width and height.
+ continue;
+ }
+ if (ctx->presentation.objects[i].composition_flag & 0x40)
+ sub->rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
+
+ sub->rects[i]->x = ctx->presentation.objects[i].x;
+ sub->rects[i]->y = ctx->presentation.objects[i].y;
+ sub->rects[i]->w = object->w;
+ sub->rects[i]->h = object->h;
+
+ sub->rects[i]->pict.linesize[0] = object->w;
+
+ if (object->rle) {
+ if (object->rle_remaining_len) {
+ av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n",
+ object->rle_data_len, object->rle_remaining_len);
+ if (avctx->err_recognition & AV_EF_EXPLODE) {
+ avsubtitle_free(sub);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ ret = decode_rle(avctx, sub->rects[i], object->rle, object->rle_data_len);
+ if (ret < 0) {
+ if ((avctx->err_recognition & AV_EF_EXPLODE) ||
+ ret == AVERROR(ENOMEM)) {
+ avsubtitle_free(sub);
+ return ret;
+ }
+ sub->rects[i]->w = 0;
+ sub->rects[i]->h = 0;
+ continue;
+ }
+ }
+ /* Allocate memory for colors */
+ sub->rects[i]->nb_colors = 256;
+ sub->rects[i]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!sub->rects[i]->pict.data[1]) {
+ avsubtitle_free(sub);
+ return AVERROR(ENOMEM);
+ }