svn merge -r36651:36672 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorCampbell Barton <ideasman42@gmail.com>
Fri, 13 May 2011 16:55:07 +0000 (16:55 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 13 May 2011 16:55:07 +0000 (16:55 +0000)
18 files changed:
build_files/buildbot/config/user-config-i686.py
build_files/buildbot/config/user-config-player-i686.py
build_files/buildbot/config/user-config-player-x86_64.py
build_files/buildbot/config/user-config-x86_64.py
build_files/scons/config/linux2-config.py
build_files/scons/tools/Blender.py
build_files/scons/tools/btools.py
source/blender/blenkernel/intern/displist.c
source/blender/blenlib/BLI_scanfill.h
source/blender/blenlib/intern/scanfill.c
source/blender/bmesh/operators/mesh_conv.c
source/blender/imbuf/CMakeLists.txt
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/SConscript
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/png.c
source/blender/imbuf/intern/tiff.c
source/blender/makesrna/intern/rna_image.c

index de8dd93982feaced688fa329d935c86a7b1fe5cf..7c7e779bdb2195631e16c73ae5a5a1a6fa63b760 100644 (file)
@@ -74,6 +74,12 @@ WITH_BF_BULLET = True
 # Blender player (would be enabled in it's own config)
 WITH_BF_PLAYER = False
 
+# Use jemalloc memory manager
+WITH_BF_JEMALLOC = True
+WITH_BF_STATICJEMALLOC = True
+BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
+BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index 202c7df6f980d19b0591ad8fe7710eec6ba8dc8b..241f5a79983111a000e5ca55cae258445dc124b1 100644 (file)
@@ -59,6 +59,12 @@ WITH_BF_BULLET = True
 WITH_BF_NOBLENDER = True
 WITH_BF_PLAYER = True
 
+# Use jemalloc memory manager
+WITH_BF_JEMALLOC = True
+WITH_BF_STATICJEMALLOC = True
+BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
+BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index 363997143e5d1cd70cb1e2cda05b17c26ffd4a5c..d51894b26cfa51a8569f52fe3516b7a7be827f9d 100644 (file)
@@ -59,6 +59,12 @@ WITH_BF_BULLET = True
 WITH_BF_NOBLENDER = True
 WITH_BF_PLAYER = True
 
+# Use jemalloc memory manager
+WITH_BF_JEMALLOC = True
+WITH_BF_STATICJEMALLOC = True
+BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
+BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index 7bae2d232cdc20d8fea8476d2ae314a1ad11e755..04489c7d06c45fd376a21d0ec6e8d2757f5e55d4 100644 (file)
@@ -74,6 +74,12 @@ WITH_BF_BULLET = True
 # Blender player (would be enabled in it's own config)
 WITH_BF_PLAYER = False
 
+# Use jemalloc memory manager
+WITH_BF_JEMALLOC = True
+WITH_BF_STATICJEMALLOC = True
+BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
+BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index d4e97c78c3843d09f9aef4791425adb58f2895aa..bc2917055fb68104f07fedfebc06eb9ade5a4d2c 100644 (file)
@@ -178,6 +178,14 @@ BF_EXPAT = '/usr'
 BF_EXPAT_LIB = 'expat'
 BF_EXPAT_LIBPATH = '/usr/lib'
 
+WITH_BF_JEMALLOC = False
+WITH_BF_STATICJEMALLOC = False
+BF_JEMALLOC = '/usr'
+BF_JEMALLOC_INC = '${BF_JEMALLOC}/include'
+BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib'
+BF_JEMALLOC_LIB = 'jemalloc'
+BF_JEMALLOC_LIB_STATIC = '${BF_JEMALLOC_LIBPATH}/libjemalloc.a'
+
 WITH_BF_OPENMP = True
 
 #Ray trace optimization
index ad4df1a60c1fe61c0fe49cb4a30bb1b4dc1e26e2..90c2c35bb98548721ee145eac770212b27eeb564 100644 (file)
@@ -203,6 +203,11 @@ def setup_staticlibs(lenv):
     if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
         libincs.append('/usr/lib')
 
+    if lenv['WITH_BF_JEMALLOC']:
+        libincs += Split(lenv['BF_JEMALLOC_LIBPATH'])
+        if lenv['WITH_BF_STATICJEMALLOC']:
+            statlibs += Split(lenv['BF_JEMALLOC_LIB_STATIC'])
+
     return statlibs, libincs
 
 def setup_syslibs(lenv):
@@ -263,6 +268,9 @@ def setup_syslibs(lenv):
     if not lenv['WITH_BF_STATICLIBSAMPLERATE']:
         syslibs += Split(lenv['BF_LIBSAMPLERATE_LIB'])
 
+    if lenv['WITH_BF_JEMALLOC']:
+        if not lenv['WITH_BF_STATICJEMALLOC']:
+            syslibs += Split(lenv['BF_JEMALLOC_LIB'])
 
     syslibs += lenv['LLIBS']
 
index fcc782bd824245e4606efda1c1da50f6e32df348..fda88d7d5a93f7a822b25879733f737584073c47 100644 (file)
@@ -134,7 +134,8 @@ def validate_arguments(args, bc):
             'WITH_BF_RAYOPTIMIZATION',
             'BF_RAYOPTIMIZATION_SSE_FLAGS',
             'BF_NO_ELBEEM',
-            'WITH_BF_CXX_GUARDEDALLOC'
+            'WITH_BF_CXX_GUARDEDALLOC',
+            'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC'
             ]
     
     # Have options here that scons expects to be lists
@@ -429,6 +430,14 @@ def read_opts(env, cfg, args):
         ('BF_EXPAT_LIB', 'Expat library', ''),
         ('BF_EXPAT_LIBPATH', 'Expat library path', ''),
         
+        (BoolVariable('WITH_BF_JEMALLOC', 'Use jemalloc if true', False)),
+        (BoolVariable('WITH_BF_STATICJEMALLOC', 'Staticly link to jemalloc', False)),
+        ('BF_JEMALLOC', 'jemalloc base path', ''),
+        ('BF_JEMALLOC_INC', 'jemalloc include path', ''),
+        ('BF_JEMALLOC_LIB', 'jemalloc library', ''),
+        ('BF_JEMALLOC_LIBPATH', 'jemalloc library path', ''),
+        ('BF_JEMALLOC_LIB_STATIC', 'jemalloc static library', ''),
+
         (BoolVariable('WITH_BF_PLAYER', 'Build blenderplayer if true', False)),
         (BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender if true', False)),
 
index a3a91c3b4420a906dbd0056e58637a2f03fa1d51..b65392a9a4722464252a5ba0fe76969abaf805e8 100644 (file)
@@ -983,16 +983,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                        dl= dl->next;
                }
                
-               if(totvert && BLI_edgefill(0)) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
-
-                       /* count faces  */
-                       tot= 0;
-                       efa= fillfacebase.first;
-                       while(efa) {
-                               tot++;
-                               efa= efa->next;
-                       }
-
+               if(totvert && (tot= BLI_edgefill(0))) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
                        if(tot) {
                                dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
                                dlnew->type= DL_INDEX3;
index b0ed92711329f213ecf50edc90e7e492822e4139..0c5e6db1826d6f9c089b9e3f0987004a854cfee2 100644 (file)
@@ -55,7 +55,7 @@ struct EditVert *BLI_addfillvert(float *vec);
 struct EditEdge *BLI_addfilledge(struct EditVert *v1, struct EditVert *v2);
 
 int BLI_begin_edgefill(void);
-int BLI_edgefill(int mat_nr);
+int BLI_edgefill(short mat_nr);
 void BLI_end_edgefill(void);
 
 /* These callbacks are needed to make the lib finction properly */
index 908e69182507e403afc5ad04d6a14ff81cf78d35..c5a5cdeb5b087c6a25c03ff26d99956589a81669 100644 (file)
@@ -27,6 +27,7 @@
  * ***** END GPL LICENSE BLOCK *****
  * (uit traces) maart 95
  */
+
 /** \file blender/blenlib/intern/scanfill.c
  *  \ingroup bli
  */
@@ -90,7 +91,6 @@ typedef struct PolyFill {
 typedef struct ScFillVert {
        EditVert *v1;
        EditEdge *first,*last;
-       short f,f1;
 } ScFillVert;
 
 
@@ -100,9 +100,9 @@ typedef struct ScFillVert {
 
 static ScFillVert *scdata;
 
-ListBase fillvertbase = {0,0};
-ListBase filledgebase = {0,0};
-ListBase fillfacebase = {0,0};
+ListBase fillvertbase = {NULL, NULL};
+ListBase filledgebase = {NULL, NULL};
+ListBase fillfacebase = {NULL, NULL};
 
 static short cox, coy;
 
@@ -236,7 +236,7 @@ EditEdge *BLI_addfilledge(EditVert *v1, EditVert *v2)
        return newed;
 }
 
-static void addfillface(EditVert *v1, EditVert *v2, EditVert *v3, int mat_nr)
+static void addfillface(EditVert *v1, EditVert *v2, EditVert *v3, short mat_nr)
 {
        /* does not make edges */
        EditFace *evl;
@@ -512,13 +512,13 @@ static void splitlist(ListBase *tempve, ListBase *temped, short nr)
 }
 
 
-static void scanfill(PolyFill *pf, int mat_nr)
+static int scanfill(PolyFill *pf, short mat_nr)
 {
        ScFillVert *sc = NULL, *sc1;
        EditVert *eve,*v1,*v2,*v3;
        EditEdge *eed,*nexted,*ed1,*ed2,*ed3;
        float miny = 0.0;
-       int a,b,verts, maxface, totface;        
+       int a,b,verts, maxface, totface;
        short nr, test, twoconnected=0;
 
        nr= pf->nr;
@@ -765,6 +765,8 @@ static void scanfill(PolyFill *pf, int mat_nr)
        }
 
        MEM_freeN(scdata);
+
+       return totface;
 }
 
 
@@ -775,7 +777,7 @@ int BLI_begin_edgefill(void)
        return 1;
 }
 
-int BLI_edgefill(int mat_nr)
+int BLI_edgefill(short mat_nr)
 {
        /*
          - fill works with its own lists, so create that first (no faces!)
@@ -783,7 +785,7 @@ int BLI_edgefill(int mat_nr)
          - struct elements xs en ys are not used here: don't hide stuff in it
          - edge flag ->f becomes 2 when it's a new edge
          - mode: & 1 is check for crossings, then create edges (TO DO )
-         - mode: & 2 is enable shortest diagonal test for quads
+         - returns number of triangle faces added.
        */
        ListBase tempve, temped;
        EditVert *eve;
@@ -791,6 +793,7 @@ int BLI_edgefill(int mat_nr)
        PolyFill *pflist,*pf;
        float limit, *minp, *maxp, *v1, *v2, norm[3], len;
        short a,c,poly=0,ok=0,toggle=0;
+       int totfaces= 0; /* total faces added */
 
        /* reset variables */
        eve= fillvertbase.first;
@@ -829,7 +832,7 @@ int BLI_edgefill(int mat_nr)
                                addfillface(eve, eve->next, eve->next->next, 0);
                                addfillface(eve->next->next, eve->next->next->next, eve, 0);
                }
-               return 1;
+               return 2;
        }
 
        /* first test vertices if they are in edges */
@@ -1093,7 +1096,7 @@ int BLI_edgefill(int mat_nr)
        for(a=0;a<poly;a++) {
                if(pf->edges>1) {
                        splitlist(&tempve,&temped,pf->nr);
-                       scanfill(pf, mat_nr);
+                       totfaces += scanfill(pf, mat_nr);
                }
                pf++;
        }
@@ -1103,6 +1106,6 @@ int BLI_edgefill(int mat_nr)
        /* FREE */
 
        MEM_freeN(pflist);
-       return 1;
 
+       return totfaces;
 }
index b59e89ff7d22f6937f7e6c43b1115097b76cd516..35a7511403cd73fe76c251c6bfb0db88bde7b8a5 100644 (file)
@@ -437,7 +437,6 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
                totface = 0;
                BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
                        EditVert *eve, *lasteve = NULL, *firsteve = NULL;
-                       EditFace *efa;
                        
                        BLI_begin_edgefill();
                        i = 0;
@@ -458,10 +457,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
                        }
 
                        BLI_addfilledge(lasteve, firsteve);
-                       BLI_edgefill(0);
-
-                       for (efa=fillfacebase.first; efa; efa=efa->next)
-                               totface++;
+                       totface += BLI_edgefill(0);
 
                        BLI_end_edgefill();
                }
index 6404ae3de75c3b6fa7c97401507b40d0c1e250ce..24f04098d0ca839b327505d7e0f1b837e2e37948 100644 (file)
@@ -146,4 +146,8 @@ if(WITH_IMAGE_HDR)
        add_definitions(-DWITH_HDR)
 endif()
 
+if(WITH_LCMS)
+       add_definitions(-DWITH_LCMS)
+endif()
+
 blender_add_lib(bf_imbuf "${SRC}" "${INC}")
index 81512adf065b685f74b858f2212f628cb2d086cd..5717a92db54f0a8ca8b136a3e1420f43b83567ad 100644 (file)
@@ -84,11 +84,18 @@ typedef struct ImBuf {
 
        /* pixels */
        unsigned int *rect;             /* pixel values stored here */
-       unsigned int *crect;    /* color corrected pixel values stored here */
        float *rect_float;              /* floating point Rect equivalent
                                                        Linear RGB color space - may need gamma correction to 
                                                        sRGB when generating 8bit representations */
-       
+
+#ifdef WITH_LCMS
+       unsigned int *crect;    /* color corrected pixel values stored here */
+       char profile_filename[256];     /* to be implemented properly, specific filename for custom profiles */
+#endif
+
+       /* resolution - pixels per meter */
+       double ppm[2];
+
        /* tiled pixel storage */
        int tilex, tiley;
        int xtiles, ytiles;
@@ -101,7 +108,6 @@ typedef struct ImBuf {
        /* parameters used by conversion between byte and float */
        float dither;                           /* random dither value, for conversion from float -> byte rect */
        short profile;                          /* color space/profile preset that the byte rect buffer represents */
-       char profile_filename[256];     /* to be implemented properly, specific filename for custom profiles */
 
        /* mipmapping */
        struct ImBuf *mipmap[IB_MIPMAP_LEVELS]; /* MipMap levels, a series of halved images */
index ecb9a89c274d5fd2cd991cb3a7bed0c6e15c0a45..59b938c3373231cb83a084119574246cf64b63af 100644 (file)
@@ -48,4 +48,7 @@ if env['WITH_BF_QUICKTIME']:
     incs += ' ../quicktime ' + env['BF_QUICKTIME_INC']
     defs.append('WITH_QUICKTIME')
 
+if env['WITH_BF_LCMS']:
+    defs.append('WITH_LCMS')
+
 env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [185,115] )
index a8b9e21331dd26cd00e3d9417672c1461d1338a5..91583f02a4969a2fa66f8e5949d6188393b10a00 100644 (file)
@@ -84,17 +84,19 @@ void imb_freerectfloatImBuf(ImBuf *ibuf)
 void imb_freerectImBuf(ImBuf *ibuf)
 {
        if(ibuf==NULL) return;
-       
+
+#ifdef WITH_LCMS
        if(ibuf->crect)
                MEM_freeN(ibuf->crect);
+       ibuf->crect= NULL;
+#endif
 
        if(ibuf->rect && (ibuf->mall & IB_rect))
                MEM_freeN(ibuf->rect);
+       ibuf->rect= NULL;
        
        imb_freemipmapImBuf(ibuf);
-       
-       ibuf->rect= NULL;
-       ibuf->crect= NULL;
+
        ibuf->mall &= ~IB_rect;
 }
 
@@ -346,6 +348,7 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flag
                ibuf->depth= d;
                ibuf->ftype= TGA;
                ibuf->channels= 4;      /* float option, is set to other values when buffers get assigned */
+               ibuf->ppm[0]= ibuf->ppm[1]= 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */
                
                if(flags & IB_rect) {
                        if(imb_addrectImBuf(ibuf)==FALSE) {
index 200ff0af9af2af6beb7fa1d1028ee7e253aa135a..6b6dcdb88afd4b729504e5c010270c7a17120b82 100644 (file)
@@ -257,6 +257,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
 
        }
 
+       if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+               png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER);
+       }
+
        // write the file header information
        png_write_info(png_ptr, info_ptr);
 
@@ -384,7 +388,19 @@ struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags)
        if (ibuf) {
                ibuf->ftype = PNG;
                ibuf->profile = IB_PROFILE_SRGB;
-       } else {
+
+               if (png_get_valid (png_ptr, info_ptr, PNG_INFO_pHYs)) {
+                       int unit_type;
+                       unsigned int xres, yres;
+
+                       if(png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type))
+                       if(unit_type == PNG_RESOLUTION_METER) {
+                               ibuf->ppm[0]= xres;
+                               ibuf->ppm[1]= yres;
+                       }
+               }
+       }
+       else {
                printf("Couldn't allocate memory for PNG image\n");
        }
 
index 67d20d564664913921ae5f820eec7571b7bc668b..36130aa0dbfedf95af10fc0dc35a425d7aecfadd 100644 (file)
@@ -354,6 +354,25 @@ static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, i
                rectf[i*4 + chan] = fbuf[i];
 }
 
+static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
+{
+       uint16 unit;
+       float xres;
+       float yres;
+
+       TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit);
+       TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres);
+       TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres);
+
+       if(unit == RESUNIT_CENTIMETER) {
+               ibuf->ppm[0]= (double)xres * 100.0;
+               ibuf->ppm[1]= (double)yres * 100.0;
+       }
+       else {
+               ibuf->ppm[0]= (double)xres / 0.0254;
+               ibuf->ppm[1]= (double)yres / 0.0254;
+       }
+}
 
 /* 
  * Use the libTIFF scanline API to read a TIFF image.
@@ -369,10 +388,13 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
        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) {
@@ -658,6 +680,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
        unsigned char *from = NULL, *to = NULL;
        unsigned short *pixels16 = NULL, *to16 = NULL;
        float *fromf = NULL;
+       float xres, yres;
        int x, y, from_i, to_i, i;
        int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
        
@@ -783,8 +806,18 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
        TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
        TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
        TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-       TIFFSetField(image, TIFFTAG_XRESOLUTION,     150.0);
-       TIFFSetField(image, TIFFTAG_YRESOLUTION,     150.0);
+
+
+       if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+               xres= (float)(ibuf->ppm[0] * 0.0254);
+               yres= (float)(ibuf->ppm[1] * 0.0254);
+       }
+       else {
+               xres= yres= 150.0f;
+       }
+
+       TIFFSetField(image, TIFFTAG_XRESOLUTION,     xres);
+       TIFFSetField(image, TIFFTAG_YRESOLUTION,     yres);
        TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT,  RESUNIT_INCH);
        if(TIFFWriteEncodedStrip(image, 0,
                        (bitspersample == 16)? (unsigned char*)pixels16: pixels,
index 5872542d10a659640c3825afb18687dca364a70d..3db90c2de0e80aee87ff8d139715d4f2ecb41ef3 100644 (file)
@@ -221,6 +221,39 @@ static void rna_Image_size_get(PointerRNA *ptr,int *values)
        BKE_image_release_ibuf(im, lock);
 }
 
+static void rna_Image_resolution_get(PointerRNA *ptr, float *values)
+{
+       Image *im= (Image*)ptr->data;
+       ImBuf *ibuf;
+       void *lock;
+
+       ibuf = BKE_image_acquire_ibuf(im, NULL , &lock);
+       if (ibuf) {
+               values[0]= ibuf->ppm[0];
+               values[1]= ibuf->ppm[1];
+       }
+       else {
+               values[0]= 0;
+               values[1]= 0;
+       }
+
+       BKE_image_release_ibuf(im, lock);
+}
+
+static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
+{
+       Image *im= (Image*)ptr->data;
+       ImBuf *ibuf;
+       void *lock;
+
+       ibuf = BKE_image_acquire_ibuf(im, NULL , &lock);
+       if (ibuf) {
+               ibuf->ppm[0]= values[0];
+               ibuf->ppm[1]= values[1];
+       }
+
+       BKE_image_release_ibuf(im, lock);
+}
 
 static int rna_Image_depth_get(PointerRNA *ptr)
 {
@@ -557,6 +590,9 @@ static void rna_def_image(BlenderRNA *brna)
        RNA_def_property_int_funcs(prop, "rna_Image_size_get" , NULL, NULL);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 
+       prop= RNA_def_float_vector(srna, "resolution" , 2 , NULL , 0, 0, "Resolution" , "X/Y pixels per meter" , 0 , 0);
+       RNA_def_property_float_funcs(prop, "rna_Image_resolution_get" , "rna_Image_resolution_set", NULL);
+
        prop= RNA_def_property(srna, "pixels", PROP_FLOAT, PROP_NONE);
        RNA_def_property_flag(prop, PROP_DYNAMIC);
        RNA_def_property_multi_array(prop, 1, NULL);