ImageGeneric(const std::vector<unsigned int>& stride, const std::vector<unsigned int>& rows, std::mt19937& rng) { // count planes assert(stride.size() == rows.size()); unsigned int planes = stride.size(); m_data.resize(planes); m_stride.resize(planes); // calculate stride and total size size_t totalsize = 0; for(unsigned int p = 0; p < planes; ++p) { m_stride[p] = grow_align16(stride[p]); totalsize += m_stride[p] * rows[p]; } // allocate buffer m_buffer.Alloc(totalsize); for(unsigned int i = 0; i < totalsize; ++i) { m_buffer[i] = rng(); } // set data uint8_t *data = m_buffer.GetData(); for(unsigned int p = 0; p < planes; ++p) { m_data[p] = data; data += m_stride[p] * rows[p]; } }
void Scale_BGRA_Generic(unsigned int in_w, unsigned int in_h, const uint8_t* in_data, int in_stride, unsigned int out_w, unsigned int out_h, uint8_t* out_data, int out_stride, MipMapFunction mipmap_function, BilinearFunction bilinear_function) { // no scaling? if(in_w == out_w && in_h == out_h) { if(in_stride == out_stride) { memcpy(out_data, in_data, in_stride * in_h); } else { for(unsigned int out_j = 0; out_j < out_h; ++out_j) { memcpy(out_data, in_data, in_w * 4); in_data += in_stride; out_data += out_stride; } } return; } // calculate mipmap factors unsigned int mx = 0, my = 0; while((out_w << (mx + 1)) <= in_w) ++mx; while((out_h << (my + 1)) <= in_h) ++my; if(mx + my > 8) { if(mx <= 4) my = 8 - mx; else if(my <= 4) mx = 8 - my; else mx = my = 4; } // pure mipmap scaling? if((out_w << mx) == in_w && (out_h << my) == in_h) { mipmap_function(in_w, in_h, in_data, in_stride, out_data, out_stride, mx, my); return; } // create mipmap TempBuffer<uint8_t> mipmap; if(mx != 0 || my != 0) { unsigned int mipmap_w = ((in_w - 1) >> mx) + 1, mipmap_h = ((in_h - 1) >> my) + 1; int mipmap_stride = grow_align16(mipmap_w * 4); mipmap.Alloc(mipmap_stride * mipmap_h); mipmap_function(in_w, in_h, in_data, in_stride, mipmap.GetData(), mipmap_stride, mx, my); in_data = mipmap.GetData(); in_stride = mipmap_stride; }