This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

Changeset 10024 for ps


Ignore:
Timestamp:
08/17/11 10:38:53 (13 years ago)
Author:
Jan Wassenberg
Message:

refactor: remove "wrapping" and "read" functionality for DynArray (in preparation for replacing it with template policies for more flexible Pool etc.)

Location:
ps/trunk/source/lib
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/source/lib/allocators/dynarray.cpp

    r9462 r10024  
    3232
    3333
    34 // indicates that this DynArray must not be resized or freed
    35 // (e.g. because it merely wraps an existing memory range).
    36 // stored in da->prot to reduce size; doesn't conflict with any PROT_* flags.
    37 const int DA_NOT_OUR_MEM = 0x40000000;
    38 
    3934static Status validate_da(DynArray* da)
    4035{
     
    5853    if(pos > cur_size || pos > max_size_pa)
    5954        WARN_RETURN(ERR::_5);
    60     if(prot & ~(PROT_READ|PROT_WRITE|PROT_EXEC|DA_NOT_OUR_MEM))
     55    if(prot & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
    6156        WARN_RETURN(ERR::_6);
    6257
     
    9287    u8* p            = da->base;
    9388    size_t size_pa   = da->max_size_pa;
    94     bool was_wrapped = (da->prot & DA_NOT_OUR_MEM) != 0;
    9589
    9690    // wipe out the DynArray for safety
     
    9892    memset(da, 0, sizeof(*da));
    9993
    100     // skip mem_Release if <da> was allocated via da_wrap_fixed
    101     // (i.e. it doesn't actually own any memory). don't complain;
    102     // da_free is supposed to be called even in the above case.
    103     if(!was_wrapped && size_pa)
     94    if(size_pa)
    10495        RETURN_STATUS_IF_ERR(mem_Release(p, size_pa));
    10596    return INFO::OK;
     
    110101{
    111102    CHECK_DA(da);
    112 
    113     if(da->prot & DA_NOT_OUR_MEM)
    114         WARN_RETURN(ERR::LOGIC);
    115103
    116104    // determine how much to add/remove
     
    155143    CHECK_DA(da);
    156144
    157     // somewhat more subtle: POSIX mprotect requires the memory have been
    158     // mmap-ed, which it probably wasn't here.
    159     if(da->prot & DA_NOT_OUR_MEM)
    160         WARN_RETURN(ERR::LOGIC);
    161 
    162145    da->prot = prot;
    163146    RETURN_STATUS_IF_ERR(mem_Protect(da->base, da->cur_size_pa, prot));
    164147
    165148    CHECK_DA(da);
    166     return INFO::OK;
    167 }
    168 
    169 
    170 Status da_wrap_fixed(DynArray* da, u8* p, size_t size)
    171 {
    172     da->base        = p;
    173     da->max_size_pa = Align<pageSize>(size);
    174     da->cur_size    = size;
    175     da->cur_size_pa = da->max_size_pa;
    176     da->prot        = PROT_READ|PROT_WRITE|DA_NOT_OUR_MEM;
    177     da->pos         = 0;
    178     CHECK_DA(da);
    179     return INFO::OK;
    180 }
    181 
    182 
    183 Status da_read(DynArray* da, void* data, size_t size)
    184 {
    185     // make sure we have enough data to read
    186     if(da->pos+size > da->cur_size)
    187         WARN_RETURN(ERR::FAIL);
    188 
    189     memcpy(data, da->base+da->pos, size);
    190     da->pos += size;
    191149    return INFO::OK;
    192150}
  • ps/trunk/source/lib/allocators/dynarray.h

    r9410 r10024  
    111111
    112112/**
    113  * "wrap" (i.e. store information about) the given buffer in a DynArray.
    114  *
    115  * this is used to allow calling da_read or da_append on normal buffers.
    116  * da_free should be called when the DynArray is no longer needed,
    117  * even though it doesn't free this memory (but does zero the DynArray).
    118  *
    119  * @param da DynArray. Note: any future operations on it that would
    120  * change the underlying memory (e.g. da_set_size) will fail.
    121  * @param p target memory (no alignment/padding requirements)
    122  * @param size maximum size (no alignment requirements)
    123  * @return Status.
    124  **/
    125 LIB_API Status da_wrap_fixed(DynArray* da, u8* p, size_t size);
    126 
    127 /**
    128  * "read" from array, i.e. copy into the given buffer.
    129  *
    130  * starts at offset DynArray.pos and advances this.
    131  *
    132  * @param da DynArray.
    133  * @param data_dst destination memory
    134  * @param size [bytes] to copy
    135  * @return Status.
    136  **/
    137 LIB_API Status da_read(DynArray* da, void* data_dst, size_t size);
    138 
    139 /**
    140113 * "write" to array, i.e. copy from the given buffer.
    141114 *
  • ps/trunk/source/lib/allocators/tests/test_allocators.h

    r9361 r10024  
    3838        TS_ASSERT_OK(da_set_prot(&da, PROT_NONE));
    3939        TS_ASSERT_OK(da_free(&da));
    40 
    41         // test wrapping existing mem blocks for use with da_read
    42         u8 data[4] = { 0x12, 0x34, 0x56, 0x78 };
    43         TS_ASSERT_OK(da_wrap_fixed(&da, data, sizeof(data)));
    44         u8 buf[4];
    45         TS_ASSERT_OK(da_read(&da, buf, 4));
    46         TS_ASSERT_EQUALS(read_le32(buf), (u32)0x78563412);  // read correct value
    47         debug_SkipErrors(ERR::FAIL);
    48         TS_ASSERT(da_read(&da, buf, 1) < 0);        // no more data left
    49         TS_ASSERT_EQUALS((uint32_t)debug_StopSkippingErrors(), (uint32_t)1);
    50         TS_ASSERT_OK(da_free(&da));
    5140    }
    5241};
  • ps/trunk/source/lib/tex/tex.cpp

    r9447 r10024  
    146146    {
    147147        // used to skip past this mip level in <data>
    148         const size_t level_data_size = (size_t)(round_up(level_w, data_padding) * round_up(level_h, data_padding) * bpp/8);
     148        const size_t level_dataSize = (size_t)(round_up(level_w, data_padding) * round_up(level_h, data_padding) * bpp/8);
    149149
    150150        if(level >= 0)
    151             cb((size_t)level, level_w, level_h, level_data, level_data_size, cbData);
    152 
    153         level_data += level_data_size;
     151            cb((size_t)level, level_w, level_h, level_data, level_dataSize, cbData);
     152
     153        level_data += level_dataSize;
    154154
    155155        // 1x1 reached - done
     
    180180    size_t prev_level_h;
    181181    const u8* prev_level_data;
    182     size_t prev_level_data_size;
     182    size_t prev_level_dataSize;
    183183};
    184184
    185185// uses 2x2 box filter
    186 static void create_level(size_t level, size_t level_w, size_t level_h, const u8* RESTRICT level_data, size_t level_data_size, void* RESTRICT cbData)
     186static void create_level(size_t level, size_t level_w, size_t level_h, const u8* RESTRICT level_data, size_t level_dataSize, void* RESTRICT cbData)
    187187{
    188188    CreateLevelData* cld = (CreateLevelData*)cbData;
     
    195195    if(level == 0)
    196196    {
    197         ENSURE(level_data_size == cld->prev_level_data_size);
    198         memcpy(dst, src, level_data_size);
     197        ENSURE(level_dataSize == cld->prev_level_dataSize);
     198        memcpy(dst, src, level_dataSize);
    199199    }
    200200    else
     
    240240        }
    241241
    242         ENSURE(dst == level_data + level_data_size);
    243         ENSURE(src == cld->prev_level_data + cld->prev_level_data_size);
     242        ENSURE(dst == level_data + level_dataSize);
     243        ENSURE(src == cld->prev_level_data + cld->prev_level_dataSize);
    244244    }
    245245
    246246    cld->prev_level_data = level_data;
    247     cld->prev_level_data_size = level_data_size;
     247    cld->prev_level_dataSize = level_dataSize;
    248248    cld->prev_level_w = level_w;
    249249    cld->prev_level_h = level_h;
     
    251251
    252252
    253 static Status add_mipmaps(Tex* t, size_t w, size_t h, size_t bpp, void* newData, size_t data_size)
     253static Status add_mipmaps(Tex* t, size_t w, size_t h, size_t bpp, void* newData, size_t dataSize)
    254254{
    255255    // this code assumes the image is of POT dimension; we don't
     
    262262    shared_ptr<u8> mipmapData;
    263263    AllocateAligned(mipmapData, mipmap_size);
    264     CreateLevelData cld = { bpp/8, w, h, (const u8*)newData, data_size };
     264    CreateLevelData cld = { bpp/8, w, h, (const u8*)newData, dataSize };
    265265    tex_util_foreach_mipmap(w, h, bpp, mipmapData.get(), 0, 1, create_level, &cld);
    266266    t->data = mipmapData;
     
    296296    const size_t w = t->w, h = t->h, bpp = t->bpp;
    297297    const size_t flags = t->flags;
    298     u8* const data = tex_get_data(t);
     298    u8* const srcStorage = tex_get_data(t);
    299299
    300300    // sanity checks (not errors, we just can't handle these cases)
     
    308308        return INFO::OK;
    309309
    310     const size_t data_size = tex_img_size(t);   // size of source
    311     size_t new_data_size = data_size;   // size of destination
     310    const size_t srcSize = tex_img_size(t);
     311    size_t dstSize = srcSize;
    312312
    313313    if(transforms & TEX_ALPHA)
     
    316316        if(bpp == 24)
    317317        {
    318             new_data_size = (data_size / 3) * 4;
     318            dstSize = (srcSize / 3) * 4;
    319319            t->bpp = 32;
    320320        }
     
    324324            return INFO::TEX_CODEC_CANNOT_HANDLE;
    325325        }
    326         // can't have alpha with greyscale
     326        // can't have alpha with grayscale
    327327        else
    328328        {
     
    338338    // this is necessary even when not flipping because the initial data
    339339    // is read-only.
    340     shared_ptr<u8> newData;
    341     AllocateAligned(newData, new_data_size);
     340    shared_ptr<u8> dstStorage;
     341    AllocateAligned(dstStorage, dstSize);
    342342
    343343    // setup row source/destination pointers (simplifies outer loop)
    344     u8* dst = (u8*)newData.get();
     344    u8* dst = (u8*)dstStorage.get();
    345345    const u8* src;
    346346    const size_t pitch = w * bpp/8; // source bpp (not necessarily dest bpp)
     
    351351    if(transforms & TEX_ORIENTATION)
    352352    {
    353         src = (const u8*)data+data_size-pitch;  // last row
     353        src = (const u8*)srcStorage+srcSize-pitch;  // last row
    354354        row_ofs = -(ssize_t)pitch;
    355355    }
     
    357357    else if(transforms & TEX_ALPHA)
    358358    {
    359         src = (const u8*)data;
     359        src = (const u8*)srcStorage;
    360360    }
    361361    // do other transforms in-place
    362362    else
    363363    {
    364         src = (const u8*)newData.get();
    365         memcpy(newData.get(), data, data_size);
     364        src = (const u8*)dstStorage.get();
     365        memcpy(dstStorage.get(), srcStorage, srcSize);
    366366    }
    367367
     
    449449    }
    450450
    451     t->data = newData;
    452     t->dataSize = new_data_size;
     451    t->data = dstStorage;
     452    t->dataSize = dstSize;
    453453    t->ofs = 0;
    454454
    455455    if(!(t->flags & TEX_MIPMAPS) && transforms & TEX_MIPMAPS)
    456         RETURN_STATUS_IF_ERR(add_mipmaps(t, w, h, bpp, newData.get(), new_data_size));
     456        RETURN_STATUS_IF_ERR(add_mipmaps(t, w, h, bpp, dstStorage.get(), dstSize));
    457457
    458458    CHECK_TEX(t);
     
    672672
    673673
    674 static void add_level_size(size_t UNUSED(level), size_t UNUSED(level_w), size_t UNUSED(level_h), const u8* RESTRICT UNUSED(level_data), size_t level_data_size, void* RESTRICT cbData)
     674static void add_level_size(size_t UNUSED(level), size_t UNUSED(level_w), size_t UNUSED(level_h), const u8* RESTRICT UNUSED(level_data), size_t level_dataSize, void* RESTRICT cbData)
    675675{
    676676    size_t* ptotal_size = (size_t*)cbData;
    677     *ptotal_size += level_data_size;
     677    *ptotal_size += level_dataSize;
    678678}
    679679
     
    715715//-----------------------------------------------------------------------------
    716716
    717 Status tex_decode(const shared_ptr<u8>& data, size_t data_size, Tex* t)
     717Status tex_decode(const shared_ptr<u8>& data, size_t dataSize, Tex* t)
    718718{
    719719    const TexCodecVTbl* c;
    720     RETURN_STATUS_IF_ERR(tex_codec_for_header(data.get(), data_size, &c));
     720    RETURN_STATUS_IF_ERR(tex_codec_for_header(data.get(), dataSize, &c));
    721721
    722722    // make sure the entire header is available
    723723    const size_t min_hdr_size = c->hdr_size(0);
    724     if(data_size < min_hdr_size)
     724    if(dataSize < min_hdr_size)
    725725        WARN_RETURN(ERR::TEX_INCOMPLETE_HEADER);
    726726    const size_t hdr_size = c->hdr_size(data.get());
    727     if(data_size < hdr_size)
     727    if(dataSize < hdr_size)
    728728        WARN_RETURN(ERR::TEX_INCOMPLETE_HEADER);
    729729
    730730    t->data = data;
    731     t->dataSize = data_size;
     731    t->dataSize = dataSize;
    732732    t->ofs = hdr_size;
    733733
    734     // for orthogonality, encode and decode both receive the memory as a
    735     // DynArray. package data into one and free it again after decoding:
    736     DynArray da;
    737     RETURN_STATUS_IF_ERR(da_wrap_fixed(&da, data.get(), data_size));
    738 
    739     RETURN_STATUS_IF_ERR(c->decode(&da, t));
    740 
    741     // note: not reached if decode fails. that's not a problem;
    742     // this call just zeroes <da> and could be left out.
    743     (void)da_free(&da);
     734    RETURN_STATUS_IF_ERR(c->decode((rpU8)data.get(), dataSize, t));
    744735
    745736    // sanity checks
  • ps/trunk/source/lib/tex/tex_bmp.cpp

    r9410 r10024  
    9696
    9797// requirements: uncompressed, direct colour, bottom up
    98 static Status bmp_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
     98static Status bmp_decode(rpU8 data, size_t UNUSED(size), Tex* RESTRICT t)
    9999{
    100     u8* file = da->base;
    101 
    102     const BmpHeader* hdr = (const BmpHeader*)file;
     100    const BmpHeader* hdr = (const BmpHeader*)data;
    103101    const long w       = (long)read_le32(&hdr->biWidth);
    104102    const long h_      = (long)read_le32(&hdr->biHeight);
  • ps/trunk/source/lib/tex/tex_codec.h

    r9410 r10024  
    4242     * decode the file into a Tex structure.
    4343     *
    44      * @param da input data array (not const, because the texture
     44     * @param data input data array (non-const, because the texture
    4545     * may have to be flipped in-place - see "texture orientation").
    46      * its size is guaranteed to be >= 4.
    47      * (usually enough to compare the header's "magic" field;
    48      * anyway, no legitimate file will be smaller)
     46     * @param size [bytes] of data, always >= 4
     47     *   (this is usually enough to compare the header's "magic" field,
     48     *    and no legitimate file will be smaller)
    4949     * @param t output texture object
    5050     * @return Status
    5151     **/
    52     Status (*decode)(DynArray* RESTRICT da, Tex * RESTRICT t);
    53 
     52    Status (*decode)(u8* data, size_t size, Tex* RESTRICT t);
    5453
    5554    /**
     
    6463     * @return Status
    6564     **/
    66     Status (*encode)(Tex* RESTRICT t, DynArray * RESTRICT da);
     65    Status (*encode)(Tex* RESTRICT t, DynArray* RESTRICT da);
    6766
    6867    /**
  • ps/trunk/source/lib/tex/tex_dds.cpp

    r9861 r10024  
    589589
    590590
    591 static Status dds_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
    592 {
    593     u8* file = da->base;
    594     const DDS_HEADER* sd = (const DDS_HEADER*)(file+4);
     591static Status dds_decode(rpU8 data, size_t UNUSED(size), Tex* RESTRICT t)
     592{
     593    const DDS_HEADER* sd = (const DDS_HEADER*)(data+4);
    595594    RETURN_STATUS_IF_ERR(decode_sd(sd, t->w, t->h, t->bpp, t->flags));
    596595    return INFO::OK;
  • ps/trunk/source/lib/tex/tex_internal.h

    r9410 r10024  
    2828#define INCLUDED_TEX_INTERNAL
    2929
     30#include "lib/pointer_typedefs.h"
    3031#include "lib/allocators/dynarray.h"
    3132#include "lib/file/io/io.h" // io::Allocate
  • ps/trunk/source/lib/tex/tex_jpg.cpp

    r9410 r10024  
    170170*/
    171171
    172 GLOBAL(void) src_prepare(j_decompress_ptr cinfo, DynArray* da)
     172GLOBAL(void) src_prepare(j_decompress_ptr cinfo, rpU8 data, size_t size)
    173173{
    174174    SrcPtr src;
    175 
    176     const u8* p = da->base;
    177     const size_t size = da->cur_size;
    178175
    179176    /* Treat 0-length buffer as fatal error */
     
    208205    */
    209206    src->pub.bytes_in_buffer   = size;
    210     src->pub.next_input_byte   = (JOCTET*)p;
     207    src->pub.next_input_byte   = (JOCTET*)data;
    211208}
    212209
     
    444441
    445442
    446 static Status jpg_decode_impl(DynArray* da, jpeg_decompress_struct* cinfo, Tex* t)
    447 {
    448     src_prepare(cinfo, da);
     443static Status jpg_decode_impl(rpU8 data, size_t size, jpeg_decompress_struct* cinfo, Tex* t)
     444{
     445    src_prepare(cinfo, data, size);
    449446
    450447    // ignore return value since:
     
    480477    // alloc destination buffer
    481478    const size_t pitch = w * bpp / 8;
    482     const size_t img_size = pitch * h;  // for allow_rows
    483     shared_ptr<u8> data;
    484     AllocateAligned(data, img_size, pageSize);
     479    const size_t imgSize = pitch * h;   // for allow_rows
     480    shared_ptr<u8> img;
     481    AllocateAligned(img, imgSize, pageSize);
    485482
    486483    // read rows
    487     std::vector<RowPtr> rows = tex_codec_alloc_rows(data.get(), h, pitch, TEX_TOP_DOWN, 0);
     484    std::vector<RowPtr> rows = tex_codec_alloc_rows(img.get(), h, pitch, TEX_TOP_DOWN, 0);
    488485    // could use cinfo->output_scanline to keep track of progress,
    489486    // but we need to count lines_left anyway (paranoia).
     
    508505
    509506    // store image info
    510     t->data  = data;
    511     t->dataSize = img_size;
     507    t->data  = img;
     508    t->dataSize = imgSize;
    512509    t->ofs   = 0;
    513510    t->w     = w;
     
    589586
    590587
    591 static Status jpg_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
     588static Status jpg_decode(rpU8 data, size_t size, Tex* RESTRICT t)
    592589{
    593590    // contains the JPEG decompression parameters and pointers to
     
    601598    jpeg_create_decompress(&cinfo);
    602599
    603     Status ret = jpg_decode_impl(da, &cinfo, t);
     600    Status ret = jpg_decode_impl(data, size, &cinfo, t);
    604601
    605602    jpeg_destroy_decompress(&cinfo); // releases a "good deal" of memory
  • ps/trunk/source/lib/tex/tex_png.cpp

    r9410 r10024  
    5050//-----------------------------------------------------------------------------
    5151
     52class MemoryStream
     53{
     54public:
     55    MemoryStream(rpU8 data, size_t size)
     56        : data(data), size(size), pos(0)
     57    {
     58    }
     59
     60    size_t RemainingSize() const
     61    {
     62        ASSERT(pos <= size);
     63        return size-pos;
     64    }
     65
     66    void CopyTo(rpU8 dst, size_t dstSize)
     67    {
     68        memcpy(dst, data+pos, dstSize);
     69        pos += dstSize;
     70    }
     71
     72private:
     73    rpU8 data;
     74    size_t size;
     75    size_t pos;
     76};
     77
    5278
    5379// pass data from PNG file in memory to libpng
    54 static void io_read(png_struct* png_ptr, u8* data, png_size_t length)
    55 {
    56     DynArray* da = (DynArray*)png_get_io_ptr(png_ptr);
    57     if(da_read(da, data, length) != 0)
    58         png_error(png_ptr, "io_read failed");
     80static void io_read(png_struct* png_ptr, rpU8 data, png_size_t size)
     81{
     82    MemoryStream* stream = (MemoryStream*)png_get_io_ptr(png_ptr);
     83    if(stream->RemainingSize() < size)
     84    {
     85        png_error(png_ptr, "PNG: not enough input");
     86        return;
     87    }
     88
     89    stream->CopyTo(data, size);
    5990}
    6091
     
    88119// split out of png_decode to simplify resource cleanup and avoid
    89120// "dtor / setjmp interaction" warning.
    90 static Status png_decode_impl(DynArray* da, png_structp png_ptr, png_infop info_ptr, Tex* t)
    91 {
    92     png_set_read_fn(png_ptr, da, io_read);
     121static Status png_decode_impl(MemoryStream* stream, png_structp png_ptr, png_infop info_ptr, Tex* t)
     122{
     123    png_set_read_fn(png_ptr, stream, io_read);
    93124
    94125    // read header and determine format
     
    121152
    122153    // success; make sure all data was consumed.
    123     ENSURE(da->pos == da->cur_size);
     154    ENSURE(stream->RemainingSize() == 0);
    124155
    125156    // store image info
    126     t->data  = data;
     157    t->data     = data;
    127158    t->dataSize = img_size;
    128159    t->ofs   = 0;
     
    201232
    202233// limitation: palette images aren't supported
    203 static Status png_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
     234static Status png_decode(rpU8 data, size_t size, Tex* RESTRICT t)
    204235{
    205236TIMER_ACCRUE(tc_png_decode);
    206237
    207     Status ret = ERR::FAIL;
    208238    png_infop info_ptr = 0;
    209239
     
    214244    info_ptr = png_create_info_struct(png_ptr);
    215245    if(!info_ptr)
    216         goto fail;
     246    {
     247        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
     248        WARN_RETURN(ERR::NO_MEM);
     249    }
    217250    // setup error handling
    218251    if(setjmp(png_jmpbuf(png_ptr)))
    219252    {
    220253        // libpng longjmps here after an error
    221         goto fail;
    222     }
    223 
    224     ret = png_decode_impl(da, png_ptr, info_ptr, t);
    225 
    226 fail:
     254        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
     255        WARN_RETURN(ERR::FAIL);
     256    }
     257
     258    MemoryStream stream(data, size);
     259    Status ret = png_decode_impl(&stream, png_ptr, info_ptr, t);
     260
    227261    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
    228262   
  • ps/trunk/source/lib/tex/tex_tga.cpp

    r9410 r10024  
    112112
    113113
    114 // requirements: uncompressed, direct colour, bottom up
    115 static Status tga_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
     114// requirements: uncompressed, direct color, bottom up
     115static Status tga_decode(rpU8 data, size_t UNUSED(size), Tex* RESTRICT t)
    116116{
    117     u8* file = da->base;
    118 
    119     TgaHeader* hdr = (TgaHeader*)file;
     117    const TgaHeader* hdr = (const TgaHeader*)data;
    120118    const u8 type  = hdr->img_type;
    121119    const size_t w   = read_le16(&hdr->w);
Note: See TracChangeset for help on using the changeset viewer.