static void index_rebuild_fallback(FallbackIndexBuilderContext *context, short *stop, short *do_update, float *progress) { int cnt = IMB_anim_get_duration(context->anim, IMB_TC_NONE); int i, pos; struct anim *anim = context->anim; for (pos = 0; pos < cnt; pos++) { struct ImBuf *ibuf = IMB_anim_absolute(anim, pos, IMB_TC_NONE, IMB_PROXY_NONE); struct ImBuf *tmp_ibuf = IMB_dupImBuf(ibuf); float next_progress = (float) pos / (float) cnt; if (*progress != next_progress) { *progress = next_progress; *do_update = TRUE; } if (*stop) { break; } IMB_flipy(tmp_ibuf); for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) { if (context->proxy_sizes_in_use & proxy_sizes[i]) { int x = anim->x * proxy_fac[i]; int y = anim->y * proxy_fac[i]; struct ImBuf *s_ibuf = IMB_dupImBuf(tmp_ibuf); IMB_scalefastImBuf(s_ibuf, x, y); IMB_convert_rgba_to_abgr(s_ibuf); AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, s_ibuf->rect, x * y * 4); /* note that libavi free's the buffer... */ s_ibuf->rect = NULL; IMB_freeImBuf(s_ibuf); } } IMB_freeImBuf(tmp_ibuf); IMB_freeImBuf(ibuf); } }
struct ImBuf *IMB_anim_absolute(struct anim *anim, int position, IMB_Timecode_Type tc, IMB_Proxy_Size preview_size) { struct ImBuf *ibuf = NULL; char head[256], tail[256]; unsigned short digits; int pic; int filter_y; if (anim == NULL) return(NULL); filter_y = (anim->ib_flags & IB_animdeinterlace); if (anim->curtype == 0) { ibuf = anim_getnew(anim); if (ibuf == NULL) { return(NULL); } IMB_freeImBuf(ibuf); /* ???? */ ibuf = NULL; } if (position < 0) return(NULL); if (position >= anim->duration) return(NULL); if (preview_size != IMB_PROXY_NONE) { struct anim *proxy = IMB_anim_open_proxy(anim, preview_size); if (proxy) { position = IMB_anim_index_get_frame_index( anim, tc, position); return IMB_anim_absolute( proxy, position, IMB_TC_NONE, IMB_PROXY_NONE); } } switch (anim->curtype) { case ANIM_SEQUENCE: pic = an_stringdec(anim->first, head, tail, &digits); pic += position; an_stringenc(anim->name, head, tail, digits, pic); ibuf = IMB_loadiffname(anim->name, IB_rect, anim->colorspace); if (ibuf) { anim->curposition = position; } break; case ANIM_MOVIE: ibuf = movie_fetchibuf(anim, position); if (ibuf) { anim->curposition = position; IMB_convert_rgba_to_abgr(ibuf); } break; #ifdef WITH_AVI case ANIM_AVI: ibuf = avi_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; #endif #ifdef WITH_QUICKTIME case ANIM_QTIME: ibuf = qtime_fetchibuf(anim, position); if (ibuf) { if (ibuf->rect) { /* OCIO_TODO: should happen in quicktime module, but it currently doesn't have access * to color management's internals */ ibuf->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace); } anim->curposition = position; } break; #endif #ifdef WITH_FFMPEG case ANIM_FFMPEG: ibuf = ffmpeg_fetchibuf(anim, position, tc); if (ibuf) anim->curposition = position; filter_y = 0; /* done internally */ break; #endif #ifdef WITH_REDCODE case ANIM_REDCODE: ibuf = redcode_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; #endif } if (ibuf) { if (filter_y) IMB_filtery(ibuf); BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1); } return(ibuf); }
/* * Use the libTIFF scanline API to read a TIFF image. * This method is most flexible and can handle multiple different bit depths * and RGB channel orderings. */ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image) { ImBuf *tmpibuf; int success = 0; short bitspersample, spp, config; size_t scanline; int ib_flag = 0, row, chan; float *fbuf = NULL; unsigned short *sbuf = NULL; TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */ TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config); if (spp == 4) { /* HACK: this is really tricky hack, which is only needed to force libtiff * do not touch RGB channels when there's alpha channel present * The thing is: libtiff will premul RGB if alpha mode is set to * unassociated, which really conflicts with blender's assumptions * * Alternative would be to unpremul after load, but it'll be really * lossy and unwanted behavior * * So let's keep this thing here for until proper solution is found (sergey) */ unsigned short extraSampleTypes[1]; extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA; TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes); } imb_read_tiff_resolution(ibuf, image); scanline = TIFFScanlineSize(image); if (bitspersample == 32) { ib_flag = IB_rectfloat; fbuf = (float *)_TIFFmalloc(scanline); } else if (bitspersample == 16) { ib_flag = IB_rectfloat; sbuf = (unsigned short *)_TIFFmalloc(scanline); } else { ib_flag = IB_rect; } tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ib_flag); /* simple RGBA image */ if (!(bitspersample == 32 || bitspersample == 16)) { success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0); } /* contiguous channels: RGBRGBRGB */ else if (config == PLANARCONFIG_CONTIG) { for (row = 0; row < ibuf->y; row++) { int ib_offset = ibuf->x * ibuf->y * 4 - ibuf->x * 4 * (row + 1); if (bitspersample == 32) { success |= TIFFReadScanline(image, fbuf, row, 0); scanline_contig_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, spp); } else if (bitspersample == 16) { success |= TIFFReadScanline(image, sbuf, row, 0); scanline_contig_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, spp); } } /* separate channels: RRRGGGBBB */ } else if (config == PLANARCONFIG_SEPARATE) { /* imbufs always have 4 channels of data, so we iterate over all of them * but only fill in from the TIFF scanline where necessary. */ for (chan = 0; chan < 4; chan++) { for (row = 0; row < ibuf->y; row++) { int ib_offset = ibuf->x * ibuf->y * 4 - ibuf->x * 4 * (row + 1); if (bitspersample == 32) { if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ fill_vn_fl(fbuf, ibuf->x, 1.0f); else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */ success |= TIFFReadScanline(image, fbuf, row, 0); else success |= TIFFReadScanline(image, fbuf, row, chan); scanline_separate_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, chan); } else if (bitspersample == 16) { if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ fill_vn_ushort(sbuf, ibuf->x, 65535); else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */ success |= TIFFReadScanline(image, fbuf, row, 0); else success |= TIFFReadScanline(image, sbuf, row, chan); scanline_separate_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, chan); } } } } if (bitspersample == 32) _TIFFfree(fbuf); else if (bitspersample == 16) _TIFFfree(sbuf); if (success) { /* Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton) */ if (bitspersample < 16) if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(tmpibuf); /* assign rect last */ if (tmpibuf->rect_float) ibuf->rect_float = tmpibuf->rect_float; else ibuf->rect = tmpibuf->rect; ibuf->mall |= ib_flag; ibuf->flags |= ib_flag; tmpibuf->mall &= ~ib_flag; } IMB_freeImBuf(tmpibuf); return success; }
/* * Use the libTIFF scanline API to read a TIFF image. * This method is most flexible and can handle multiple different bit depths * and RGB channel orderings. */ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) { ImBuf *tmpibuf; int success= 0; short bitspersample, spp, config; size_t scanline; int ib_flag=0, row, chan; float *fbuf=NULL; unsigned short *sbuf=NULL; TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */ TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config); imb_read_tiff_resolution(ibuf, image); scanline = TIFFScanlineSize(image); if (bitspersample == 32) { ib_flag = IB_rectfloat; fbuf = (float *)_TIFFmalloc(scanline); } else if (bitspersample == 16) { ib_flag = IB_rectfloat; sbuf = (unsigned short *)_TIFFmalloc(scanline); } else { ib_flag = IB_rect; } tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ib_flag); /* simple RGBA image */ if (!(bitspersample == 32 || bitspersample == 16)) { success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0); } /* contiguous channels: RGBRGBRGB */ else if (config == PLANARCONFIG_CONTIG) { for (row = 0; row < ibuf->y; row++) { int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1); if (bitspersample == 32) { success |= TIFFReadScanline(image, fbuf, row, 0); scanline_contig_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, spp); } else if (bitspersample == 16) { success |= TIFFReadScanline(image, sbuf, row, 0); scanline_contig_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, spp); } } /* separate channels: RRRGGGBBB */ } else if (config == PLANARCONFIG_SEPARATE) { /* imbufs always have 4 channels of data, so we iterate over all of them * but only fill in from the TIFF scanline where necessary. */ for (chan = 0; chan < 4; chan++) { for (row = 0; row < ibuf->y; row++) { int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1); if (bitspersample == 32) { if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ fill_vn_fl(fbuf, ibuf->x, 1.0f); else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */ success |= TIFFReadScanline(image, fbuf, row, 0); else success |= TIFFReadScanline(image, fbuf, row, chan); scanline_separate_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, chan); } else if (bitspersample == 16) { if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ fill_vn_ushort(sbuf, ibuf->x, 65535); else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */ success |= TIFFReadScanline(image, fbuf, row, 0); else success |= TIFFReadScanline(image, sbuf, row, chan); scanline_separate_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, chan); } } } } if (bitspersample == 32) _TIFFfree(fbuf); else if (bitspersample == 16) _TIFFfree(sbuf); if (success) { ibuf->profile = (bitspersample==32)?IB_PROFILE_LINEAR_RGB:IB_PROFILE_SRGB; // Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton) if (bitspersample < 16) if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(tmpibuf); if (premul) { IMB_premultiply_alpha(tmpibuf); ibuf->flags |= IB_premul; } /* assign rect last */ if (tmpibuf->rect_float) ibuf->rect_float= tmpibuf->rect_float; else ibuf->rect= tmpibuf->rect; ibuf->mall |= ib_flag; ibuf->flags |= ib_flag; tmpibuf->mall &= ~ib_flag; } IMB_freeImBuf(tmpibuf); return success; }
static void index_rebuild_fallback(struct anim * anim, IMB_Timecode_Type UNUSED(tcs_in_use), IMB_Proxy_Size proxy_sizes_in_use, int quality, short *stop, short *do_update, float *progress) { int cnt = IMB_anim_get_duration(anim, IMB_TC_NONE); int i, pos; AviMovie * proxy_ctx[IMB_PROXY_MAX_SLOT]; char fname[FILE_MAXDIR+FILE_MAXFILE]; char fname_tmp[FILE_MAXDIR+FILE_MAXFILE]; memset(proxy_ctx, 0, sizeof(proxy_ctx)); /* since timecode indices only work with ffmpeg right now, don't know a sensible fallback here... so no proxies, no game to play... */ if (proxy_sizes_in_use == IMB_PROXY_NONE) { return; } for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) { if (proxy_sizes_in_use & proxy_sizes[i]) { char fname[FILE_MAXDIR+FILE_MAXFILE]; get_proxy_filename(anim, proxy_sizes[i], fname, TRUE); BLI_make_existing_file(fname); proxy_ctx[i] = alloc_proxy_output_avi( anim, fname, anim->x * proxy_fac[i], anim->y * proxy_fac[i], quality); } } for (pos = 0; pos < cnt; pos++) { struct ImBuf * ibuf = IMB_anim_absolute( anim, pos, IMB_TC_NONE, IMB_PROXY_NONE); int next_progress = (int) ((double) pos / (double) cnt); if (*progress != next_progress) { *progress = next_progress; *do_update = 1; } if (*stop) { break; } IMB_flipy(ibuf); for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) { if (proxy_sizes_in_use & proxy_sizes[i]) { int x = anim->x * proxy_fac[i]; int y = anim->y * proxy_fac[i]; struct ImBuf * s_ibuf = IMB_scalefastImBuf( ibuf, x, y); IMB_convert_rgba_to_abgr(s_ibuf); AVI_write_frame (proxy_ctx[i], pos, AVI_FORMAT_RGB32, s_ibuf->rect, x * y * 4); /* note that libavi free's the buffer... */ s_ibuf->rect = 0; IMB_freeImBuf(s_ibuf); } } } for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) { if (proxy_sizes_in_use & proxy_sizes[i]) { AVI_close_compress (proxy_ctx[i]); MEM_freeN (proxy_ctx[i]); get_proxy_filename(anim, proxy_sizes[i], fname_tmp, TRUE); get_proxy_filename(anim, proxy_sizes[i], fname, FALSE); if (*stop) { unlink(fname_tmp); } else { rename(fname_tmp, fname); } } } }
int do_paintface_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) { Object *ob = vc->obact; Mesh *me; MPoly *mpoly; struct ImBuf *ibuf; unsigned int *rt; char *selar; int a, index; const int size[2] = { BLI_rcti_size_x(rect) + 1, BLI_rcti_size_y(rect) + 1}; me = BKE_mesh_from_object(ob); if ((me == NULL) || (me->totpoly == 0) || (size[0] * size[1] <= 0)) { return OPERATOR_CANCELLED; } selar = MEM_callocN(me->totpoly + 1, "selar"); if (extend == false && select) { paintface_deselect_all_visible(vc->obact, SEL_DESELECT, false); mpoly = me->mpoly; for (a = 1; a <= me->totpoly; a++, mpoly++) { if ((mpoly->flag & ME_HIDE) == 0) mpoly->flag &= ~ME_FACE_SEL; } } ED_view3d_backbuf_validate(vc); ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect); rt = ibuf->rect; view3d_opengl_read_pixels(vc->ar, rect->xmin, rect->ymin, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); if (ENDIAN_ORDER == B_ENDIAN) { IMB_convert_rgba_to_abgr(ibuf); } GPU_select_to_index_array(ibuf->rect, size[0] * size[1]); a = size[0] * size[1]; while (a--) { if (*rt) { index = *rt; if (index <= me->totpoly) { selar[index] = 1; } } rt++; } mpoly = me->mpoly; for (a = 1; a <= me->totpoly; a++, mpoly++) { if (selar[a]) { if (mpoly->flag & ME_HIDE) { /* pass */ } else { if (select) mpoly->flag |= ME_FACE_SEL; else mpoly->flag &= ~ME_FACE_SEL; } } } IMB_freeImBuf(ibuf); MEM_freeN(selar); #ifdef __APPLE__ glReadBuffer(GL_BACK); #endif paintface_flush_flags(vc->obact, SELECT); return OPERATOR_FINISHED; }
struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { struct ImBuf * ibuf = NULL; char head[256], tail[256]; unsigned short digits; int pic; int filter_y; if (anim == NULL) return(NULL); filter_y = (anim->ib_flags & IB_animdeinterlace); if (anim->curtype == 0) { ibuf = anim_getnew(anim); if (ibuf == NULL) { return(NULL); } IMB_freeImBuf(ibuf); /* ???? */ ibuf= NULL; } if (position < 0) return(NULL); if (position >= anim->duration) return(NULL); switch(anim->curtype) { case ANIM_SEQUENCE: pic = an_stringdec(anim->first, head, tail, &digits); pic += position; an_stringenc(anim->name, head, tail, digits, pic); ibuf = IMB_loadiffname(anim->name, IB_rect); if (ibuf) { anim->curposition = position; } break; case ANIM_MOVIE: ibuf = movie_fetchibuf(anim, position); if (ibuf) { anim->curposition = position; IMB_convert_rgba_to_abgr(ibuf); ibuf->profile = IB_PROFILE_SRGB; } break; case ANIM_AVI: ibuf = avi_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; #ifdef WITH_QUICKTIME case ANIM_QTIME: ibuf = qtime_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; #endif #ifdef WITH_FFMPEG case ANIM_FFMPEG: ibuf = ffmpeg_fetchibuf(anim, position); if (ibuf) anim->curposition = position; filter_y = 0; /* done internally */ break; #endif #ifdef WITH_REDCODE case ANIM_REDCODE: ibuf = redcode_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; #endif } if (ibuf) { if (filter_y) IMB_filtery(ibuf); sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1); } return(ibuf); }