Blender V2.61 - r43446

image_draw.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Blender Foundation, 2002-2009
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <math.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 
00035 #include "MEM_guardedalloc.h"
00036 
00037 #include "DNA_camera_types.h"
00038 #include "DNA_object_types.h"
00039 #include "DNA_space_types.h"
00040 #include "DNA_scene_types.h"
00041 #include "DNA_screen_types.h"
00042 #include "DNA_brush_types.h"
00043 
00044 #include "PIL_time.h"
00045 
00046 #include "BLI_math.h"
00047 #include "BLI_threads.h"
00048 #include "BLI_string.h"
00049 #include "BLI_utildefines.h"
00050 
00051 #include "IMB_imbuf.h"
00052 #include "IMB_imbuf_types.h"
00053 
00054 #include "BKE_context.h"
00055 #include "BKE_global.h"
00056 #include "BKE_image.h"
00057 #include "BKE_paint.h"
00058 
00059 #include "BIF_gl.h"
00060 #include "BIF_glutil.h"
00061 
00062 #include "BLF_api.h"
00063 
00064 #include "ED_gpencil.h"
00065 #include "ED_image.h"
00066 #include "ED_screen.h"
00067 
00068 #include "UI_interface.h"
00069 #include "UI_resources.h"
00070 #include "UI_view2d.h"
00071 
00072 
00073 #include "RE_pipeline.h"
00074 
00075 #include "image_intern.h"
00076 
00077 #define HEADER_HEIGHT 18
00078 
00079 static void image_verify_buffer_float(Image *ima, ImBuf *ibuf, int color_manage)
00080 {
00081     /* detect if we need to redo the curve map.
00082        ibuf->rect is zero for compositor and render results after change 
00083        convert to 32 bits always... drawing float rects isnt supported well (atis)
00084     
00085        NOTE: if float buffer changes, we have to manually remove the rect
00086     */
00087 
00088     if(ibuf->rect_float && (ibuf->rect==NULL || (ibuf->userflags & IB_RECT_INVALID)) ) {
00089         if(color_manage) {
00090             if(ima && ima->source == IMA_SRC_VIEWER)
00091                 ibuf->profile = IB_PROFILE_LINEAR_RGB;
00092         }
00093         else
00094             ibuf->profile = IB_PROFILE_NONE;
00095 
00096         IMB_rect_from_float(ibuf);
00097     }
00098 }
00099 
00100 static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
00101 {
00102     RenderResult *rr;
00103     
00104     rr= BKE_image_acquire_renderresult(scene, ima);
00105 
00106     if(rr && rr->text) {
00107         ED_region_info_draw(ar, rr->text, 1, 0.25);
00108     }
00109 
00110     BKE_image_release_renderresult(scene, ima);
00111 }
00112 
00113 /* used by node view too */
00114 void ED_image_draw_info(ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf)
00115 {
00116     char str[256];
00117     float dx= 6;
00118     /* text colors */
00119     /* XXX colored text not allowed in Blender UI */
00120     #if 0
00121     unsigned char red[3] = {255, 50, 50};
00122     unsigned char green[3] = {0, 255, 0};
00123     unsigned char blue[3] = {100, 100, 255};
00124     #else
00125     unsigned char red[3] = {255, 255, 255};
00126     unsigned char green[3] = {255, 255, 255};
00127     unsigned char blue[3] = {255, 255, 255};
00128     #endif
00129     float hue=0, sat=0, val=0, lum=0, u=0, v=0;
00130     float col[4], finalcol[4];
00131 
00132     glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00133     glEnable(GL_BLEND);
00134 
00135     /* noisy, high contrast make impossible to read if lower alpha is used. */
00136     glColor4ub(0, 0, 0, 190);
00137     glRecti(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 20);
00138     glDisable(GL_BLEND);
00139 
00140     BLF_size(blf_mono_font, 11, 72);
00141 
00142     glColor3ub(255, 255, 255);
00143     BLI_snprintf(str, sizeof(str), "X:%-4d  Y:%-4d |", x, y);
00144     // UI_DrawString(6, 6, str); // works ok but fixed width is nicer.
00145     BLF_position(blf_mono_font, dx, 6, 0);
00146     BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00147     dx += BLF_width(blf_mono_font, str);
00148 
00149     if(zp) {
00150         glColor3ub(255, 255, 255);
00151         BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff));
00152         BLF_position(blf_mono_font, dx, 6, 0);
00153         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00154         dx += BLF_width(blf_mono_font, str);
00155     }
00156     if(zpf) {
00157         glColor3ub(255, 255, 255);
00158         BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
00159         BLF_position(blf_mono_font, dx, 6, 0);
00160         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00161         dx += BLF_width(blf_mono_font, str);
00162     }
00163 
00164     if(channels >= 3) {
00165         glColor3ubv(red);
00166         if (fp)
00167             BLI_snprintf(str, sizeof(str), "  R:%-.4f", fp[0]);
00168         else if (cp)
00169             BLI_snprintf(str, sizeof(str), "  R:%-3d", cp[0]);
00170         else
00171             BLI_snprintf(str, sizeof(str), "  R:-");
00172         BLF_position(blf_mono_font, dx, 6, 0);
00173         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00174         dx += BLF_width(blf_mono_font, str);
00175         
00176         glColor3ubv(green);
00177         if (fp)
00178             BLI_snprintf(str, sizeof(str), "  G:%-.4f", fp[1]);
00179         else if (cp)
00180             BLI_snprintf(str, sizeof(str), "  G:%-3d", cp[1]);
00181         else
00182             BLI_snprintf(str, sizeof(str), "  G:-");
00183         BLF_position(blf_mono_font, dx, 6, 0);
00184         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00185         dx += BLF_width(blf_mono_font, str);
00186         
00187         glColor3ubv(blue);
00188         if (fp)
00189             BLI_snprintf(str, sizeof(str), "  B:%-.4f", fp[2]);
00190         else if (cp)
00191             BLI_snprintf(str, sizeof(str), "  B:%-3d", cp[2]);
00192         else
00193             BLI_snprintf(str, sizeof(str), "  B:-");
00194         BLF_position(blf_mono_font, dx, 6, 0);
00195         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00196         dx += BLF_width(blf_mono_font, str);
00197         
00198         if(channels == 4) {
00199             glColor3ub(255, 255, 255);
00200             if (fp)
00201                 BLI_snprintf(str, sizeof(str), "  A:%-.4f", fp[3]);
00202             else if (cp)
00203                 BLI_snprintf(str, sizeof(str), "  A:%-3d", cp[3]);
00204             else
00205                 BLI_snprintf(str, sizeof(str), "- ");
00206             BLF_position(blf_mono_font, dx, 6, 0);
00207             BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00208             dx += BLF_width(blf_mono_font, str);
00209         }
00210     }
00211     
00212     /* color rectangle */
00213     if (channels==1) {
00214         if (fp)
00215             col[0] = col[1] = col[2] = fp[0];
00216         else if (cp)
00217             col[0] = col[1] = col[2] = (float)cp[0]/255.0f;
00218         else
00219             col[0] = col[1] = col[2] = 0.0f;
00220     }
00221     else if (channels==3) {
00222         if (fp)
00223             copy_v3_v3(col, fp);
00224         else if (cp) {
00225             col[0] = (float)cp[0]/255.0f;
00226             col[1] = (float)cp[1]/255.0f;
00227             col[2] = (float)cp[2]/255.0f;
00228         }
00229         else
00230             zero_v3(col);
00231     }
00232     else if (channels==4) {
00233         if (fp)
00234             copy_v4_v4(col, fp);
00235         else if (cp) {
00236             col[0] = (float)cp[0]/255.0f;
00237             col[1] = (float)cp[1]/255.0f;
00238             col[2] = (float)cp[2]/255.0f;
00239             col[3] = (float)cp[3]/255.0f;
00240         }
00241         else
00242             zero_v4(col);
00243     }
00244     if (color_manage) {
00245         linearrgb_to_srgb_v3_v3(finalcol, col);
00246         finalcol[3] = col[3];
00247     }
00248     else {
00249         copy_v4_v4(finalcol, col);
00250     }
00251     glDisable(GL_BLEND);
00252     glColor3fv(finalcol);
00253     dx += 5;
00254     glBegin(GL_QUADS);
00255     glVertex2f(dx, 3);
00256     glVertex2f(dx, 17);
00257     glVertex2f(dx+30, 17);
00258     glVertex2f(dx+30, 3);
00259     glEnd();
00260     dx += 35;
00261 
00262     glColor3ub(255, 255, 255);
00263     if(channels == 1) {
00264         if (fp) {
00265             rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
00266             rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v);
00267         }
00268         else if (cp) {
00269             rgb_to_hsv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &hue, &sat, &val);
00270             rgb_to_yuv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &lum, &u, &v);
00271         }
00272         
00273         BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
00274         BLF_position(blf_mono_font, dx, 6, 0);
00275         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00276         dx += BLF_width(blf_mono_font, str);
00277 
00278         BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
00279         BLF_position(blf_mono_font, dx, 6, 0);
00280         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00281         dx += BLF_width(blf_mono_font, str);
00282     }
00283     else if(channels >= 3) {
00284         if (fp) {
00285             rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val);
00286             rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v);
00287         }
00288         else if (cp) {
00289             rgb_to_hsv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &hue, &sat, &val);
00290             rgb_to_yuv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &lum, &u, &v);
00291         }
00292 
00293         BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
00294         BLF_position(blf_mono_font, dx, 6, 0);
00295         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00296         dx += BLF_width(blf_mono_font, str);
00297 
00298         BLI_snprintf(str, sizeof(str), "  S:%-.4f", sat);
00299         BLF_position(blf_mono_font, dx, 6, 0);
00300         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00301         dx += BLF_width(blf_mono_font, str);
00302 
00303         BLI_snprintf(str, sizeof(str), "  V:%-.4f", val);
00304         BLF_position(blf_mono_font, dx, 6, 0);
00305         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00306         dx += BLF_width(blf_mono_font, str);
00307 
00308         BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
00309         BLF_position(blf_mono_font, dx, 6, 0);
00310         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
00311         dx += BLF_width(blf_mono_font, str);
00312     }
00313 
00314     (void)dx;
00315 }
00316 
00317 /* image drawing */
00318 
00319 static void draw_image_grid(ARegion *ar, float zoomx, float zoomy)
00320 {
00321     float gridsize, gridstep= 1.0f/32.0f;
00322     float fac, blendfac;
00323     int x1, y1, x2, y2;
00324     
00325     /* the image is located inside (0,0),(1, 1) as set by view2d */
00326     UI_ThemeColorShade(TH_BACK, 20);
00327 
00328     UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
00329     UI_view2d_to_region_no_clip(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
00330     glRectf(x1, y1, x2, y2);
00331 
00332     /* gridsize adapted to zoom level */
00333     gridsize= 0.5f*(zoomx+zoomy);
00334     if(gridsize<=0.0f) return;
00335     
00336     if(gridsize<1.0f) {
00337         while(gridsize<1.0f) {
00338             gridsize*= 4.0f;
00339             gridstep*= 4.0f;
00340         }
00341     }
00342     else {
00343         while(gridsize>=4.0f) {
00344             gridsize/= 4.0f;
00345             gridstep/= 4.0f;
00346         }
00347     }
00348     
00349     /* the fine resolution level */
00350     blendfac= 0.25f*gridsize - floorf(0.25f*gridsize);
00351     CLAMP(blendfac, 0.0f, 1.0f);
00352     UI_ThemeColorShade(TH_BACK, (int)(20.0f*(1.0f-blendfac)));
00353     
00354     fac= 0.0f;
00355     glBegin(GL_LINES);
00356     while(fac<1.0f) {
00357         glVertex2f(x1, y1*(1.0f-fac) + y2*fac);
00358         glVertex2f(x2, y1*(1.0f-fac) + y2*fac);
00359         glVertex2f(x1*(1.0f-fac) + x2*fac, y1);
00360         glVertex2f(x1*(1.0f-fac) + x2*fac, y2);
00361         fac+= gridstep;
00362     }
00363     
00364     /* the large resolution level */
00365     UI_ThemeColor(TH_BACK);
00366     
00367     fac= 0.0f;
00368     while(fac<1.0f) {
00369         glVertex2f(x1, y1*(1.0f-fac) + y2*fac);
00370         glVertex2f(x2, y1*(1.0f-fac) + y2*fac);
00371         glVertex2f(x1*(1.0f-fac) + x2*fac, y1);
00372         glVertex2f(x1*(1.0f-fac) + x2*fac, y2);
00373         fac+= 4.0f*gridstep;
00374     }
00375     glEnd();
00376 }
00377 
00378 static void sima_draw_alpha_backdrop(float x1, float y1, float xsize, float ysize, float zoomx, float zoomy, unsigned char col1[3], unsigned char col2[3])
00379 {
00380     GLubyte checker_stipple[32*32/8] =
00381     {
00382         255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,
00383         255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,
00384         255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,
00385         255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,
00386         0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,
00387         0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,
00388         0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,
00389         0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,
00390     };
00391     
00392     glColor3ubv(col1);
00393     glRectf(x1, y1, x1 + zoomx*xsize, y1 + zoomy*ysize);
00394     glColor3ubv(col2);
00395 
00396     glEnable(GL_POLYGON_STIPPLE);
00397     glPolygonStipple(checker_stipple);
00398     glRectf(x1, y1, x1 + zoomx*xsize, y1 + zoomy*ysize);
00399     glDisable(GL_POLYGON_STIPPLE);
00400 }
00401 
00402 static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti)
00403 {
00404     
00405     /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
00406     if(ENDIAN_ORDER == B_ENDIAN)
00407         glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
00408 
00409     glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_UNSIGNED_INT, recti);
00410     glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
00411 }
00412 
00413 static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, float *rectf)
00414 {
00415     float *trectf= MEM_mallocN(rectx*recty*4, "temp");
00416     int a, b;
00417     
00418     for(a= rectx*recty -1, b= 4*a+3; a>=0; a--, b-=4)
00419         trectf[a]= rectf[b];
00420     
00421     glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, trectf);
00422     MEM_freeN(trectf);
00423     /* ogl trick below is slower... (on ATI 9600) */
00424 //  glColorMask(1, 0, 0, 0);
00425 //  glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+3);
00426 //  glColorMask(0, 1, 0, 0);
00427 //  glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+2);
00428 //  glColorMask(0, 0, 1, 0);
00429 //  glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+1);
00430 //  glColorMask(1, 1, 1, 1);
00431 }
00432 
00433 static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti)
00434 {
00435     /* zbuffer values are signed, so we need to shift color range */
00436     glPixelTransferf(GL_RED_SCALE, 0.5f);
00437     glPixelTransferf(GL_GREEN_SCALE, 0.5f);
00438     glPixelTransferf(GL_BLUE_SCALE, 0.5f);
00439     glPixelTransferf(GL_RED_BIAS, 0.5f);
00440     glPixelTransferf(GL_GREEN_BIAS, 0.5f);
00441     glPixelTransferf(GL_BLUE_BIAS, 0.5f);
00442     
00443     glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_INT, recti);
00444     
00445     glPixelTransferf(GL_RED_SCALE, 1.0f);
00446     glPixelTransferf(GL_GREEN_SCALE, 1.0f);
00447     glPixelTransferf(GL_BLUE_SCALE, 1.0f);
00448     glPixelTransferf(GL_RED_BIAS, 0.0f);
00449     glPixelTransferf(GL_GREEN_BIAS, 0.0f);
00450     glPixelTransferf(GL_BLUE_BIAS, 0.0f);
00451 }
00452 
00453 static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rectx, int recty, float *rect_float)
00454 {
00455     float bias, scale, *rectf, clipend;
00456     int a;
00457     
00458     if(scene->camera && scene->camera->type==OB_CAMERA) {
00459         bias= ((Camera *)scene->camera->data)->clipsta;
00460         clipend= ((Camera *)scene->camera->data)->clipend;
00461         scale= 1.0f/(clipend-bias);
00462     }
00463     else {
00464         bias= 0.1f;
00465         scale= 0.01f;
00466         clipend= 100.0f;
00467     }
00468     
00469     rectf= MEM_mallocN(rectx*recty*4, "temp");
00470     for(a= rectx*recty -1; a>=0; a--) {
00471         if(rect_float[a]>clipend)
00472             rectf[a]= 0.0f;
00473         else if(rect_float[a]<bias)
00474             rectf[a]= 1.0f;
00475         else {
00476             rectf[a]= 1.0f - (rect_float[a]-bias)*scale;
00477             rectf[a]*= rectf[a];
00478         }
00479     }
00480     glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, rectf);
00481     
00482     MEM_freeN(rectf);
00483 }
00484 
00485 static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
00486 {
00487     int x, y;
00488     int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
00489 
00490     /* set zoom */
00491     glPixelZoom(zoomx, zoomy);
00492 
00493     /* find window pixel coordinates of origin */
00494     UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y);
00495 
00496     /* this part is generic image display */
00497     if(sima->flag & SI_SHOW_ALPHA) {
00498         if(ibuf->rect)
00499             sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect);
00500         else if(ibuf->rect_float && ibuf->channels==4)
00501             sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float);
00502     }
00503     else if(sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1))) {
00504         if(ibuf->zbuf)
00505             sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf);
00506         else if(ibuf->zbuf_float)
00507             sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float);
00508         else if(ibuf->channels==1)
00509             sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float);
00510     }
00511     else {
00512         if(sima->flag & SI_USE_ALPHA) {
00513             unsigned char col1[3]= {100, 100, 100}, col2[3]= {160, 160, 160};
00514             sima_draw_alpha_backdrop(x, y, ibuf->x, ibuf->y, zoomx, zoomy, col1, col2);
00515 
00516             glEnable(GL_BLEND);
00517             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00518         }
00519 
00520         /* we don't draw floats buffers directly but
00521          * convert them, and optionally apply curves */
00522         image_verify_buffer_float(ima, ibuf, color_manage);
00523 
00524         if(ibuf->rect)
00525             glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
00526         /*else
00527             glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);*/
00528         
00529         if(sima->flag & SI_USE_ALPHA)
00530             glDisable(GL_BLEND);
00531     }
00532 
00533     /* reset zoom */
00534     glPixelZoom(1.0f, 1.0f);
00535 }
00536 
00537 static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy)
00538 {
00539     unsigned int *rt, *rp, *rectmain;
00540     short y, heigth, len;
00541 
00542     /* the right offset in rectot */
00543 
00544     rt= ibuf->rect+ (starty*ibuf->x+ startx);
00545 
00546     len= (endx-startx);
00547     heigth= (endy-starty);
00548 
00549     rp=rectmain= MEM_mallocN(heigth*len*sizeof(int), "rect");
00550     
00551     for(y=0; y<heigth; y++) {
00552         memcpy(rp, rt, len*4);
00553         rt+= ibuf->x;
00554         rp+= len;
00555     }
00556     return rectmain;
00557 }
00558 
00559 static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
00560 {
00561     unsigned int *rect;
00562     int dx, dy, sx, sy, x, y;
00563     int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
00564 
00565     /* verify valid values, just leave this a while */
00566     if(ima->xrep<1) return;
00567     if(ima->yrep<1) return;
00568     
00569     glPixelZoom(zoomx, zoomy);
00570 
00571     if(sima->curtile >= ima->xrep*ima->yrep) 
00572         sima->curtile = ima->xrep*ima->yrep - 1; 
00573     
00574     /* create char buffer from float if needed */
00575     image_verify_buffer_float(ima, ibuf, color_manage);
00576 
00577     /* retrieve part of image buffer */
00578     dx= ibuf->x/ima->xrep;
00579     dy= ibuf->y/ima->yrep;
00580     sx= (sima->curtile % ima->xrep)*dx;
00581     sy= (sima->curtile / ima->xrep)*dy;
00582     rect= get_part_from_ibuf(ibuf, sx, sy, sx+dx, sy+dy);
00583     
00584     /* draw repeated */
00585     for(sy=0; sy+dy<=ibuf->y; sy+= dy) {
00586         for(sx=0; sx+dx<=ibuf->x; sx+= dx) {
00587             UI_view2d_to_region_no_clip(&ar->v2d, fx + (float)sx/(float)ibuf->x, fy + (float)sy/(float)ibuf->y, &x, &y);
00588 
00589             glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect);
00590         }
00591     }
00592 
00593     glPixelZoom(1.0f, 1.0f);
00594 
00595     MEM_freeN(rect);
00596 }
00597 
00598 static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
00599 {
00600     const double time_current= PIL_check_seconds_timer();
00601 
00602     const int xmax= ceil(ar->v2d.cur.xmax);
00603     const int ymax= ceil(ar->v2d.cur.ymax);
00604     const int xmin= floor(ar->v2d.cur.xmin);
00605     const int ymin= floor(ar->v2d.cur.ymin);
00606 
00607     int x;
00608 
00609     for(x=xmin; x<xmax; x++) {
00610         int y;
00611         for(y=ymin; y<ymax; y++) { 
00612             if(ima && (ima->tpageflag & IMA_TILES))
00613                 draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy);
00614             else
00615                 draw_image_buffer(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy);
00616 
00617             /* only draw until running out of time */
00618             if((PIL_check_seconds_timer() - time_current) > 0.25)
00619                 return;
00620         }
00621     }
00622 }
00623 
00624 /* draw uv edit */
00625 
00626 /* draw grease pencil */
00627 void draw_image_grease_pencil(bContext *C, short onlyv2d)
00628 {
00629     /* draw in View2D space? */
00630     if (onlyv2d) {
00631         /* assume that UI_view2d_ortho(C) has been called... */
00632         SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C);
00633         void *lock;
00634         ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
00635         
00636         /* draw grease-pencil ('image' strokes) */
00637         //if (sima->flag & SI_DISPGP)
00638             draw_gpencil_2dimage(C, ibuf);
00639 
00640         ED_space_image_release_buffer(sima, lock);
00641     }
00642     else {
00643         /* assume that UI_view2d_restore(C) has been called... */
00644         //SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C);
00645         
00646         /* draw grease-pencil ('screen' strokes) */
00647         //if (sima->flag & SI_DISPGP)
00648             draw_gpencil_view2d(C, 0);
00649     }
00650 }
00651 
00652 /* XXX becomes WM paint cursor */
00653 #if 0
00654 static void draw_image_view_tool(Scene *scene)
00655 {
00656     ToolSettings *settings= scene->toolsettings;
00657     Brush *brush= settings->imapaint.brush;
00658     int mval[2];
00659     float radius;
00660     int draw= 0;
00661 
00662     if(brush) {
00663         if(settings->imapaint.flag & IMAGEPAINT_DRAWING) {
00664             if(settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL_DRAWING)
00665                 draw= 1;
00666         }
00667         else if(settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL)
00668             draw= 1;
00669         
00670         if(draw) {
00671             getmouseco_areawin(mval);
00672 
00673             radius= brush_size(brush)*G.sima->zoom;
00674             fdrawXORcirc(mval[0], mval[1], radius);
00675 
00676             if (brush->innerradius != 1.0) {
00677                 radius *= brush->innerradius;
00678                 fdrawXORcirc(mval[0], mval[1], radius);
00679             }
00680         }
00681     }
00682 }
00683 #endif
00684 
00685 static unsigned char *get_alpha_clone_image(Scene *scene, int *width, int *height)
00686 {
00687     Brush *brush = paint_brush(&scene->toolsettings->imapaint.paint);
00688     ImBuf *ibuf;
00689     unsigned int size, alpha;
00690     unsigned char *rect, *cp;
00691 
00692     if(!brush || !brush->clone.image)
00693         return NULL;
00694     
00695     ibuf= BKE_image_get_ibuf(brush->clone.image, NULL);
00696 
00697     if(!ibuf || !ibuf->rect)
00698         return NULL;
00699 
00700     rect= MEM_dupallocN(ibuf->rect);
00701     if(!rect)
00702         return NULL;
00703 
00704     *width= ibuf->x;
00705     *height= ibuf->y;
00706 
00707     size= (*width)*(*height);
00708     alpha= (unsigned char)255*brush->clone.alpha;
00709     cp= rect;
00710 
00711     while(size-- > 0) {
00712         cp[3]= alpha;
00713         cp += 4;
00714     }
00715 
00716     return rect;
00717 }
00718 
00719 static void draw_image_paint_helpers(ARegion *ar, Scene *scene, float zoomx, float zoomy)
00720 {
00721     Brush *brush;
00722     int x, y, w, h;
00723     unsigned char *clonerect;
00724 
00725     brush= paint_brush(&scene->toolsettings->imapaint.paint);
00726 
00727     if(brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE)) {
00728         /* this is not very efficient, but glDrawPixels doesn't allow
00729            drawing with alpha */
00730         clonerect= get_alpha_clone_image(scene, &w, &h);
00731 
00732         if(clonerect) {
00733             UI_view2d_to_region_no_clip(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
00734 
00735             glPixelZoom(zoomx, zoomy);
00736 
00737             glEnable(GL_BLEND);
00738             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00739             glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, clonerect);
00740             glDisable(GL_BLEND);
00741 
00742             glPixelZoom(1.0, 1.0);
00743 
00744             MEM_freeN(clonerect);
00745         }
00746     }
00747 }
00748 
00749 /* draw main image area */
00750 
00751 void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
00752 {
00753     Image *ima;
00754     ImBuf *ibuf;
00755     float zoomx, zoomy;
00756     int show_viewer, show_render;
00757     void *lock;
00758 
00759     /* XXX can we do this in refresh? */
00760 #if 0
00761     what_image(sima);
00762     
00763     if(sima->image) {
00764         ED_image_aspect(sima->image, &xuser_asp, &yuser_asp);
00765         
00766         /* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */
00767         if(sima->image->type==IMA_TYPE_COMPOSITE) {
00768             ImageUser *iuser= ntree_get_active_iuser(scene->nodetree);
00769             if(iuser) {
00770                 BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0);
00771                 sima->iuser= *iuser;
00772             }
00773         }
00774         /* and we check for spare */
00775         ibuf= ED_space_image_buffer(sima);
00776     }
00777 #endif
00778 
00779     /* retrieve the image and information about it */
00780     ima= ED_space_image(sima);
00781     ED_space_image_zoom(sima, ar, &zoomx, &zoomy);
00782     ibuf= ED_space_image_acquire_buffer(sima, &lock);
00783 
00784     show_viewer= (ima && ima->source == IMA_SRC_VIEWER);
00785     show_render= (show_viewer && ima->type == IMA_TYPE_R_RESULT);
00786 
00787     /* draw the image or grid */
00788     if(ibuf==NULL)
00789         draw_image_grid(ar, zoomx, zoomy);
00790     else if(sima->flag & SI_DRAW_TILE)
00791         draw_image_buffer_repeated(sima, ar, scene, ima, ibuf, zoomx, zoomy);
00792     else if(ima && (ima->tpageflag & IMA_TILES))
00793         draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy);
00794     else
00795         draw_image_buffer(sima, ar, scene, ima, ibuf, 0.0f, 0.0f, zoomx, zoomy);
00796 
00797     /* paint helpers */
00798     if(sima->flag & SI_DRAWTOOL)
00799         draw_image_paint_helpers(ar, scene, zoomx, zoomy);
00800 
00801 
00802     /* XXX integrate this code */
00803 #if 0
00804     if(ibuf) {
00805         float xoffs=0.0f, yoffs= 0.0f;
00806         
00807         if(image_preview_active(sa, &xim, &yim)) {
00808             xoffs= scene->r.disprect.xmin;
00809             yoffs= scene->r.disprect.ymin;
00810             glColor3ub(0,0,0);
00811             calc_image_view(sima, 'f'); 
00812             myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
00813             glRectf(0.0f, 0.0f, 1.0f, 1.0f);
00814             glLoadIdentity();
00815         }
00816     }
00817 #endif
00818 
00819     ED_space_image_release_buffer(sima, lock);
00820 
00821     /* render info */
00822     if(ima && show_render)
00823         draw_render_info(scene, ima, ar);
00824 }
00825