Example #1
0
#include "RVirtualFunction.h"
#include "../RVirtualMachine/RVirtualMachine.h"

constructor(RVirtualFunction)) {
    object = allocator(RVirtualFunction);
    if(object != nil) {
        object->classId = registerClassOnce(toString(RVirtualFunction));
        object->name = nil;
    }
    return object;
}

destructor(RVirtualFunction) {
    deleter(master(object, RData), RData);
    nilDeleter(object->name, RString);
}

printer(RVirtualFunction) {
    size_t iterator;
    RPrintf("%s object - %p : \n", toString(RVirtualFunction), object);
    RPrintf("Name : ");
    p(RString)(object->name);
    RPrintf("Byte Code : \n");

    forAll(iterator, master(object, RData)->size) {
        RPrintf("\t %lu - ",iterator);
        switch (master(object, RData)->data[iterator]) {

            case r_increment : {
                RPrintLn("incr");
            } break;
void MemoryDealer::dump(const char* what) const
{
    allocator()->dump(what);
}
Example #3
0
void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
 check_w_h_constraint_t constraint, rgba_surface_allocator_t allocator)
{
  png_uint_32 i, w, h, stride;
  png_structp png_ptr = NULL;
  png_bytep *row_ptrs = NULL;
  png_infop info_ptr = NULL;
  void *pixels, *s = NULL;
  png_byte header[8];
  int type, bpp;
  FILE *f;

  f = fopen_unsafe(name, "rb");
  if(!f)
    goto exit_out;

  if(fread(header, 1, 8, f) < 8)
    goto exit_close;

  if(png_sig_cmp(header, 0, 8))
    goto exit_close;

  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if(!png_ptr)
    goto exit_close;

  info_ptr = png_create_info_struct(png_ptr);
  if(!info_ptr)
    goto exit_free_close;

  if(setjmp(png_ptr->jmpbuf))
    goto exit_free_close;

  png_init_io(png_ptr, f);
  png_set_sig_bytes(png_ptr, 8);
  png_read_info(png_ptr, info_ptr);
  png_get_IHDR(png_ptr, info_ptr, &w, &h, &bpp, &type, NULL, NULL, NULL);

  if(!constraint(w, h))
  {
    warn("Requested image '%s' failed dimension checks.\n", name);
    goto exit_free_close;
  }

  if(type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png_ptr);

  else if(type == PNG_COLOR_TYPE_GRAY_ALPHA || !(type & PNG_COLOR_MASK_COLOR))
    png_set_gray_to_rgb(png_ptr);

  else if(!(type & PNG_COLOR_MASK_COLOR) && bpp < 8)
    png_set_expand_gray_1_2_4_to_8(png_ptr);

  if(bpp == 16)
    png_set_strip_16(png_ptr);

  else if(bpp < 8)
    png_set_packing(png_ptr);

  if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png_ptr);

  else if(!(type & PNG_COLOR_MASK_ALPHA))
    png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);

  // FIXME: Are these necessary?
  png_read_update_info(png_ptr, info_ptr);
  png_get_IHDR(png_ptr, info_ptr, &w, &h, &bpp, &type, NULL, NULL, NULL);

  row_ptrs = cmalloc(sizeof(png_bytep) * h);
  if(!row_ptrs)
    goto exit_free_close;

  s = allocator(w, h, &stride, &pixels);
  if(!s)
    goto exit_free_close;

  for(i = 0; i < h; i++)
    row_ptrs[i] = (png_bytep)(unsigned char *)pixels + i * stride;

  png_read_image(png_ptr, row_ptrs);

  if(_w)
    *_w = w;
  if(_h)
    *_h = h;

exit_free_close:
  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  free(row_ptrs);
exit_close:
  fclose(f);
exit_out:
  return s;
}
Example #4
0
 explicit BufferObject(GLsizei count)
     : _vector(count, 0) 
 { 
     allocator(count, _vector.data()); 
 }
Example #5
0
bool Encoder::learn(const char *templfile,
                    const char *trainfile,
                    const char *modelfile,
                    bool textmodelfile,
                    size_t maxitr,
                    size_t freq,
                    double eta,
                    double C,
                    unsigned short thread_num,
                    unsigned short shrinking_size,
                    int algorithm) {
  std::cout << COPYRIGHT << std::endl;

  CHECK_FALSE(eta > 0.0) << "eta must be > 0.0";
  CHECK_FALSE(C >= 0.0) << "C must be >= 0.0";
  CHECK_FALSE(shrinking_size >= 1) << "shrinking-size must be >= 1";
  CHECK_FALSE(thread_num > 0) << "thread must be > 0";

#ifndef CRFPP_USE_THREAD
  CHECK_FALSE(thread_num == 1)
      << "This architecture doesn't support multi-thrading";
#endif

  if (algorithm == MIRA && thread_num > 1) {
    std::cerr <<  "MIRA doesn't support multi-thrading. use thread_num=1"
              << std::endl;
  }

  EncoderFeatureIndex feature_index;
  Allocator allocator(thread_num);
  std::vector<TaggerImpl* > x;

  std::cout.setf(std::ios::fixed, std::ios::floatfield);
  std::cout.precision(5);

#define WHAT_ERROR(msg) do {                                    \
    for (std::vector<TaggerImpl *>::iterator it = x.begin();    \
         it != x.end(); ++it)  {                                \
         if (*it != NULL) {                                     \
             delete *it;                                        \
	         *it = 0;                                           \
		 }                                                      \
    }                                                           \
    std::cerr << msg << std::endl;                              \
    return false; } while (0)

  CHECK_FALSE(feature_index.open(templfile, trainfile))
      << feature_index.what();

  {
    progress_timer pg;

    std::ifstream ifs(WPATH(trainfile));
    CHECK_FALSE(ifs) << "cannot open: " << trainfile;

    std::cout << "reading training data: " << std::flush;
    size_t line = 0;
    while (ifs) {
      TaggerImpl *_x = new TaggerImpl();
      _x->open(&feature_index, &allocator);
      if (!_x->read(&ifs) || !_x->shrink()) {
        WHAT_ERROR(_x->what());
      }

      if (!_x->empty()) {
        x.push_back(_x);
      } else {
        delete _x;
        continue;
      }

      _x->set_thread_id(line % thread_num);

      if (++line % 100 == 0) {
        std::cout << line << ".. " << std::flush;
      }
    }

    ifs.close();
    std::cout << "\nDone!";
  }

  feature_index.shrink(freq, &allocator);

  std::vector <double> alpha(feature_index.size());           // parameter
  std::fill(alpha.begin(), alpha.end(), 0.0);
  feature_index.set_alpha(&alpha[0]);

  std::cout << "Number of sentences: " << x.size() << std::endl;
  std::cout << "Number of features:  " << feature_index.size() << std::endl;
  std::cout << "Number of thread(s): " << thread_num << std::endl;
  std::cout << "Freq:                " << freq << std::endl;
  std::cout << "eta:                 " << eta << std::endl;
  std::cout << "C:                   " << C << std::endl;
  std::cout << "shrinking size:      " << shrinking_size
            << std::endl;
  std::cout << "algorithm is " << algorithm << std::endl;

  progress_timer pg;

  switch (algorithm) {
    case MIRA:
      if (!runMIRA(x, &feature_index, &alpha[0],
                   maxitr, C, eta, shrinking_size, thread_num)) {
        WHAT_ERROR("MIRA execute error");
      }
      break;
    case CRF_L2:
      if (!runCRF(x, &feature_index, &alpha[0],
                  maxitr, C, eta, shrinking_size, thread_num, false)) {
        WHAT_ERROR("CRF_L2 execute error");
      }
      break;
    case CRF_L1:
      if (!runCRF(x, &feature_index, &alpha[0],
                  maxitr, C, eta, shrinking_size, thread_num, true)) {
        WHAT_ERROR("CRF_L1 execute error");
      }
      break;
  }

  std::cout << "done running algorithm" << std::endl;

  for (std::vector<TaggerImpl *>::iterator it = x.begin();
       it != x.end(); ++it) {
       if (*it != NULL) {                                     
           delete *it;
	       *it = 0;
       }
  }

  if (!feature_index.save(modelfile, textmodelfile)) {
    WHAT_ERROR(feature_index.what());
  }

  std::cout << "\nDone!";

  return true;
}
Example #6
0
void *operator new(std::size_t size, std::nothrow_t& nothrow) throw() { return allocator(size); }
Example #7
0
ReachabilityResult IndexedBestFS::reachable(const PetriNet &net,
											const MarkVal *m0,
											const VarVal *v0,
											const BoolVal *ba,
											PQL::Condition *query){
	StateAllocator<> allocator(net);

	State* s0 = allocator.createState();
	memcpy(s0->marking(), m0, sizeof(MarkVal) * net.numberOfPlaces());
	memcpy(s0->intValuation(), v0, sizeof(VarVal) * net.numberOfIntVariables());
	memcpy(s0->boolValuation(), ba, sizeof(BoolVal) * net.numberOfBoolVariables());

	if(query->evaluate(*s0))
		return ReachabilityResult(ReachabilityResult::Satisfied, "Satisfied initially", 0, 0);

	//Initialize subclasses
	MonotonicityContext context(&net, query);
	context.analyze();

	//Initialise StateSet
	IndexedBestFSStateSet states(net, &context, _distanceStrategy, query, _varianceFirst);
	states.add(s0);

	//Allocate new state
	State* ns = allocator.createState();
	int count = 0;
	BigInt expandedStates = 0;
	BigInt exploredStates = 0;
	BigInt transitionFired  = 0;
	size_t max = 1;
	State* s = states.getNextState();
	while(s){
		if(count++ & 1<<16){
			count = 0;
			if(states.waitingSize() > max)
				max = states.waitingSize();
			this->reportProgress((double)(max - states.waitingSize()) / ((double)(max)));
			if(this->abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										  "Query aborted!");
		}

		// Attempt to fire each transition
		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			if(net.fire(t, s, ns)){
				//If it's new
				transitionFired++;
				if(states.add(ns)){
					exploredStates++;
					//Set parent and transition for the state
					ns->setParent(s);
					ns->setTransition(t);

					//Test query
					if(query->evaluate(*ns)){
						//ns->dumpTrace(net);
						return ReachabilityResult(ReachabilityResult::Satisfied,
												  "Query was satified!", expandedStates, exploredStates, transitionFired, states.getCountRemove(), ns->pathLength(), ns->trace());
					}

					//Allocate new state, as states take ownership
					ns = allocator.createState();
				}
			}
		}
		//Take something out of the queue
		expandedStates++;
		s = states.getNextState();
	}

	return ReachabilityResult(ReachabilityResult::NotSatisfied,
							  "Query cannot be satisfied!", expandedStates, exploredStates, transitionFired, states.getCountRemove());
}
Example #8
0
Impl::AllocationTracker HostSpace::allocate_and_track( const std::string & label, const size_t size )
{
  return Impl::AllocationTracker( allocator(), size, label );
}
Example #9
0
ExecutableAllocator::ExecutableAllocator(VM&)
{
    ASSERT(allocator());
}
Example #10
0
bool FixWinding(SkPath* path) {
    SkPath::FillType fillType = path->getFillType();
    if (fillType == SkPath::kInverseEvenOdd_FillType) {
        fillType = SkPath::kInverseWinding_FillType;
    } else if (fillType == SkPath::kEvenOdd_FillType) {
        fillType = SkPath::kWinding_FillType;
    }
    SkPathPriv::FirstDirection dir;
    if (one_contour(*path) && SkPathPriv::CheapComputeFirstDirection(*path, &dir)) {
        if (dir != SkPathPriv::kCCW_FirstDirection) {
            SkPath temp;
            temp.reverseAddPath(*path);
            *path = temp;
        }
        path->setFillType(fillType);
        return true;
    }
    SkChunkAlloc allocator(4096);
    SkOpContourHead contourHead;
    SkOpGlobalState globalState(nullptr, &contourHead  SkDEBUGPARAMS(false)
            SkDEBUGPARAMS(nullptr));
    SkOpEdgeBuilder builder(*path, &contourHead, &allocator, &globalState);
    builder.finish(&allocator);
    if (!contourHead.next()) {
        return false;
    }
    contourHead.resetReverse();
    bool writePath = false;
    SkOpSpan* topSpan;
    globalState.setPhase(SkOpGlobalState::kFixWinding);
    while ((topSpan = FindSortableTop(&contourHead))) {
        SkOpSegment* topSegment = topSpan->segment();
        SkOpContour* topContour = topSegment->contour();
        SkASSERT(topContour->isCcw() >= 0);
#if DEBUG_WINDING
        SkDebugf("%s id=%d nested=%d ccw=%d\n",  __FUNCTION__,
                topSegment->debugID(), globalState.nested(), topContour->isCcw());
#endif
        if ((globalState.nested() & 1) != SkToBool(topContour->isCcw())) {
            topContour->setReverse();
            writePath = true;
        }
        topContour->markDone();
        globalState.clearNested();
    }
    if (!writePath) {
        path->setFillType(fillType);
        return true;
    }
    SkPath empty;
    SkPathWriter woundPath(empty);
    SkOpContour* test = &contourHead;
    do {
        if (test->reversed()) {
            test->toReversePath(&woundPath);
        } else {
            test->toPath(&woundPath);
        }
    } while ((test = test->next()));
    *path = *woundPath.nativePath();
    path->setFillType(fillType);
    return true;
}
Example #11
0
ReachabilityResult MagicSearch::reachable(const PetriNet &net,
										  const MarkVal *m0,
										  const VarVal *v0,
										  PQL::Condition *query){
	SmartStateAllocator<MEMORY_BOUND> allocator(net);
	SmartStateSet states(net);
	EnhancedPriorityQueue<Step> queue;

	_dm = new Structures::DistanceMatrix(net);
	{	//Compute constraints
		ConstraintAnalysisContext context(net);
		query->findConstraints(context);
		if(context.canAnalyze)
			contraints = context.retval;
	}

	//Create s0
	SmartState* s0 = allocator.createStoredState();
	memcpy(s0->marking(), m0, sizeof(MarkVal) * net.numberOfPlaces());
	memcpy(s0->valuation(), v0, sizeof(VarVal) * net.numberOfVariables());
	states.add(s0, s0->marking(), s0->valuation());
	Step step0;
	step0.depth = 0;
	step0.lastApprox = INT_MAX;
	step0.lastStored = 0;
	step0.state = s0;
	queue.push(0, step0);

	//Temporary marking and valuation to work with
	MarkVal tmpM[net.numberOfPlaces()];
	VarVal tmpV[net.numberOfVariables()];
	SmartState* ns = allocator.createStoredState();
	SmartState* ls = allocator.createState();

	//Statistics
	int lastReport = 0;
	BigInt expanded = 0, explored = 0;
	size_t max = 1;

	//Main loop
	while(!queue.empty()){
		// Report progress if needed
		if(lastReport++ & 1<<17){
			lastReport = 0;
			if(queue.size() > max)
				max = queue.size();
			this->reportProgress((double)(max - queue.size()) / ((double)(max)));
			if(this->abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										  "Query aborted!");
		}

		//Pop stuff of the queue
		Step step = queue.pop(depthFirst);
		expanded++; //Cound expanded states

		// Get current state
		const MarkVal* m;
		const VarVal* v;
		if(step.state->stored()){
			m = step.state->marking();
			v = step.state->valuation();
		}else{
			step.state->getState(net, tmpM, tmpV);
			m = tmpM;
			v = tmpV;
		}

		//Attempt to exclude by over-approx
		if(step.lastApprox >= approxScale(step.depth)){
			if(canExcludeByOverApprox(net, m, v))
				continue;
			step.lastApprox = 0;
		}

		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			//Fire the transition
			if(net.fire(t, m, v, ns->marking(), ns->valuation())){
				//Determine whether or not to store the entire state
				bool storeCurrentState = step.lastStored >= storeScale(allocator.percentMemoryUsed());// storeScale(allocator.percentMemoryUsed());
				SmartState* storeState;
				if(storeCurrentState)
					storeState = ns;
				else
					storeState = ls;
				storeState->setParent(step.state);
				storeState->setTransition(t);

				//Add it to the state set
				if(states.add(storeState, ns->marking(), ns->valuation())){
					explored++; //Count explored states

					//Test the query
					if(query->evaluate(EvaluationContext(ns->marking(), ns->valuation()))){
						printf("\nmemory usage: %f\n",allocator.percentMemoryUsed());
						return ReachabilityResult(ReachabilityResult::Satisfied,
												  "Query was satified!",
												  expanded,
												  explored,
												  storeState->pathLength(),
												  storeState->trace());
					}

					//Make the next step
					Step nextstep;
					nextstep.depth = step.depth + 1;
					nextstep.lastApprox = step.lastApprox + 1;
					if(storeState == ns)
						nextstep.lastStored = 0;
					else
						nextstep.lastStored = step.lastStored + 1;
					nextstep.state = storeState;

					//Push step on the queue
					double p = priority(ns->marking(), ns->valuation(), query, net);
					queue.push(p, nextstep);

					//Allocate new memory, depending on what was stored
					if(storeState == ns)
						ns = allocator.createStoredState();
					else
						ls = allocator.createState();
				}
			}
		}
	}
	return ReachabilityResult(ReachabilityResult::NotSatisfied,
							  "Query cannot be satisfied!",
							  expanded,
							  explored);
}
Example #12
0
bool readSubreddits(const Options& options)
{
	for (int i = 0; i < (int)options.subreddits.size(); i++)
	{
		if (gTotal >= options.maxToOpen)
			break;

		// open subreddit
		if (options.openSubreddit)
			openUrl("http://www.reddit.com/r/" + options.subreddits[i]);

		vector<HistoryItem> history;
		loadHistory(options.subreddits[i], history);

		if (options.clearHistory)
			history.clear();

		// continue if we don't actual need to fetch the json
		if (options.openLink || options.openPermalink)
		{
			// fetch the url from the server
			string server = string("www.reddit.com");
			string path   = string("/r/") + options.subreddits[i] + string("/.json?limit=") + toStr(options.numToOpen);

			string page = fetchUrl(server, path);

			if (page.size() > 0)
			{
				// convert to json
				block_allocator allocator(1 << 10);
				json_value* root = toJson(page, allocator);
				if (root)
				{
					// find the data we want. this is gross.
					for (json_value* it = root->first_child; it; it = it->next_sibling)
					{
						if (!strcmp(it->name, "data") && it->type == JSON_OBJECT)
						{
							json_value* data = it;
							for (json_value* it = data->first_child; it; it = it->next_sibling)
							{
								if (!strcmp(it->name, "children") && it->type == JSON_ARRAY)
								{
									json_value* child = it;
									for (json_value* it = child->first_child; it; it = it->next_sibling)
									{
										json_value* rec = it;
										for (json_value* it = rec->first_child; it; it = it->next_sibling)
										{
											if (!strcmp(it->name, "data"))
												handleStory(options, history, it);
											if (gTotal >= options.maxToOpen)
												goto out;
										}						
									}
								}
							}
						}
					}
				}
			}
		}
out:
		if (history.size() || options.clearHistory)
			saveHistory(options.subreddits[i], history);
	}

	return true;
}
Example #13
0
/**************************************************************************************
 *
 * This stage performs value numbering based copy propagation. Since copy propagation
 * is about data flow, we cannot find them in assertion prop phase. In assertion prop
 * we can identify copies that like so: if (a == b) else, i.e., control flow assertions.
 *
 * To identify data flow copies, we follow a similar approach to SSA renaming. We walk
 * each path in the graph keeping track of every live definition. Thus when we see a
 * variable that shares the VN with a live definition, we'd replace this variable with
 * the variable in the live definition.
 *
 * We do this to be in conventional SSA form. This can very well be changed later.
 *
 * For example, on some path in the graph:
 *    a0 = x0
 *    :            <- other blocks
 *    :
 *    a1 = y0
 *    :
 *    :            <- other blocks
 *    b0 = x0, we cannot substitute x0 with a0, because currently our backend doesn't
 * treat lclNum and ssaNum together as a variable, but just looks at lclNum. If we
 * substituted x0 with a0, then we'd be in general SSA form.
 *
 */
void Compiler::optVnCopyProp()
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In optVnCopyProp()\n");
    }
#endif

    if (fgSsaPassesCompleted == 0)
    {
        return;
    }
    jitstd::allocator<void> allocator(getAllocator());

    // Compute the domTree to use.
    BlkToBlkSetMap* domTree = new (getAllocator()) BlkToBlkSetMap(getAllocator());
    SsaBuilder::ComputeDominators(this, domTree);

    struct BlockWork
    {
        BasicBlock* m_blk;
        bool m_processed;

        BlockWork(BasicBlock* blk, bool processed = false)
            : m_blk(blk)
            , m_processed(processed)
        {}
    };
    typedef jitstd::vector<BlockWork> BlockWorkStack;

    VarSetOps::AssignNoCopy(this, compCurLife, VarSetOps::MakeEmpty(this));
    VarSetOps::AssignNoCopy(this, optCopyPropKillSet, VarSetOps::MakeEmpty(this));

    // The map from lclNum to its recently live definitions as a stack.
    LclNumToGenTreePtrStack curSsaName(getAllocator());

    BlockWorkStack* worklist = new (allocate_any<BlockWorkStack>(allocator), jitstd::placement_t()) BlockWorkStack(allocator);

    worklist->push_back(BlockWork(fgFirstBB));
    while (!worklist->empty())
    {
        BlockWork work = worklist->back();
        worklist->pop_back();

        BasicBlock* block = work.m_blk;
        if (work.m_processed)
        {
            // Pop all the live definitions for this block.
            optBlockCopyPropPopStacks(block, &curSsaName);
            continue;
        }

        // Generate copy assertions in this block, and keeping curSsaName variable up to date.
        worklist->push_back(BlockWork(block, true));

        optBlockCopyProp(block, &curSsaName);

        // Add dom children to work on.
        BlkSet* pBlkSet;
        if (domTree->Lookup(block, &pBlkSet))
        {
            for (BlkSet::KeyIterator child = pBlkSet->Begin(); !child.Equal(pBlkSet->End()); ++child)
            {
                worklist->push_back(BlockWork(child.Get()));
            }
        }
    }

    // Tracked variable count increases after CopyProp, so don't keep a shorter array around.
    // Destroy (release) the varset.
    VarSetOps::AssignNoCopy(this, compCurLife, VarSetOps::UninitVal());
}
Example #14
0
TEST(Alloc, Create)
{
  register void **stack asm ("ebp");
  alloc allocator(stack);
}
Example #15
0
Sprite *Blitter_8bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
{
	/* Make memory for all zoom-levels */
	uint memory = sizeof(SpriteData);

	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
		memory += UnScaleByZoom(sprite->height, i) * UnScaleByZoom(sprite->width, i);
	}

	/* We have no idea how much memory we really need, so just guess something */
	memory *= 5;

	/* Don't allocate memory each time, but just keep some
	 * memory around as this function is called quite often
	 * and the memory usage is quite low. */
	static ReusableBuffer<byte> temp_buffer;
	SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
	byte *dst = temp_dst->data;

	/* Make the sprites per zoom-level */
	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
		/* Store the index table */
		uint offset = dst - temp_dst->data;
		temp_dst->offset[i] = offset;

		/* cache values, because compiler can't cache it */
		int scaled_height = UnScaleByZoom(sprite->height, i);
		int scaled_width  = UnScaleByZoom(sprite->width,  i);
		int scaled_1      =   ScaleByZoom(1,              i);

		for (int y = 0; y < scaled_height; y++) {
			uint trans = 0;
			uint pixels = 0;
			uint last_colour = 0;
			byte *count_dst = NULL;

			/* Store the scaled image */
			const SpriteLoader::CommonPixel *src = &sprite->data[ScaleByZoom(y, i) * sprite->width];
			const SpriteLoader::CommonPixel *src_end = &src[sprite->width];

			for (int x = 0; x < scaled_width; x++) {
				uint colour = 0;

				/* Get the colour keeping in mind the zoom-level */
				for (int j = 0; j < scaled_1; j++) {
					if (src->m != 0) colour = src->m;
					/* Because of the scaling it might happen we read outside the buffer. Avoid that. */
					if (++src == src_end) break;
				}

				if (last_colour == 0 || colour == 0 || pixels == 255) {
					if (count_dst != NULL) {
						/* Write how many non-transparent bytes we get */
						*count_dst = pixels;
						pixels = 0;
						count_dst = NULL;
					}
					/* As long as we find transparency bytes, keep counting */
					if (colour == 0) {
						last_colour = 0;
						trans++;
						continue;
					}
					/* No longer transparency, so write the amount of transparent bytes */
					*dst = trans;
					dst++;
					trans = 0;
					/* Reserve a byte for the pixel counter */
					count_dst = dst;
					dst++;
				}
				last_colour = colour;
				pixels++;
				*dst = colour;
				dst++;
			}

			if (count_dst != NULL) *count_dst = pixels;

			/* Write line-ending */
			*dst = 0; dst++;
			*dst = 0; dst++;
		}
	}

	uint size = dst - (byte *)temp_dst;

	/* Safety check, to make sure we guessed the size correctly */
	assert(size < memory);

	/* Allocate the exact amount of memory we need */
	Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + size);

	dest_sprite->height = sprite->height;
	dest_sprite->width  = sprite->width;
	dest_sprite->x_offs = sprite->x_offs;
	dest_sprite->y_offs = sprite->y_offs;
	memcpy(dest_sprite->data, temp_dst, size);

	return dest_sprite;
}
Example #16
0
RefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
{
    RefPtr<ExecutableMemoryHandle> result = allocator()->allocate(sizeInBytes, ownerUID);
    RELEASE_ASSERT(result || effort != JITCompilationMustSucceed);
    return result;
}
Example #17
0
void *operator new(std::size_t size) throw() { return allocator(size); }
Example #18
0
D3DSDevice
D3DSDevice::CreateDevice( 
	GSPGPU_FramebufferFormats FBFormatTop,
	GSPGPU_FramebufferFormats FBFormatBottom,
	bool					  bVRamBuffers,
	bool                      bEnable3D ) 
{

    D3DSDevice device;

    device.m_b3DEnabled     = bEnable3D;
    device.m_FBFormatTop    = FBFormatTop;
    device.m_FBFormatBottom = FBFormatBottom;

    // select allocator
    void* (*allocator)(size_t);

    if (bVRamBuffers)
    {
        allocator = vramAlloc;
        device.dealloc   = vramFree;
    }
    else
    {
        allocator = linearAlloc;
        device.dealloc   = linearFree;
    }

    gspInit();

    device.m_pSharedMemory = (u8*) mappableAlloc( 0x1000 );

    GSPGPU_AcquireRight( 0x0 );

    // create shared memory
    svcCreateEvent( &device.m_hGSPEvent, 0x0 );
    GSPGPU_RegisterInterruptRelayQueue( device.m_hGSPEvent, 0x1, &device.m_hGSPSharedMemory, &device.m_ThreadId );
    svcMapMemoryBlock( device.m_hGSPSharedMemory, 
        (u32)device.m_pSharedMemory, 
        (MemPerm)(MEMPERM_READ|MEMPERM_WRITE), 
        MEMPERM_DONTCARE );

    // allocate framebuffers...
    u32 bytes_top    = 400 * 240 * D3DSDevice::GetBytesPerPixel( FBFormatTop );
    u32 bytes_bottom = 320 * 240 * D3DSDevice::GetBytesPerPixel( FBFormatBottom );

    device.m_FBBottom[0] = (u8*) allocator( bytes_bottom );
    device.m_FBBottom[1] = (u8*) allocator( bytes_bottom );
    device.m_FBTop[ 0 ]  = (u8*) allocator( bytes_top );
    device.m_FBTop[ 1 ]  = (u8*) allocator( bytes_top );
    if (device.m_b3DEnabled)
    {
        device.m_FBTop[ 2 ]  = (u8*) allocator( bytes_top );
        device.m_FBTop[ 3 ]  = (u8*) allocator( bytes_top );
    }

    device.SetFramebufferInfo( D3DS_SCREEN_TOP, 0 );
    device.SetFramebufferInfo( D3DS_SCREEN_BOTTOM, 0 );

    gxCmdBuf = (u32*) (device.m_pSharedMemory + 0x800 + device.m_ThreadId*0x200 );

    gspInitEventHandler( device.m_hGSPEvent, (vu8*)device.m_pSharedMemory, device.m_ThreadId );
    gspWaitForVBlank();


    GSPGPU_SetLcdForceBlack( 0x0 );

	return device;
}
Example #19
0
void kinectCapture::setup(bool _bTwoKinects, int _iLeftKinectId, int _iRightKinectId) {
    
    
    bTwoKinects = _bTwoKinects;
    
    bMovementDetection = true;
    
    // SETUP KINECT ONE
    
    fKin1Angle = 0;
    
    bool success = false;
    int counter = 0;
    
    kinect1.init(false, false);
    kinect1.open(_iLeftKinectId);
    
    if(bTwoKinects) {
        fKin2Angle = 0;
        
        kinect2.init(false, false);
        kinect2.open(_iRightKinectId);
    
    }
    
    kinect1.update();
    kinect1.setCameraTiltAngle(0);
    kinect1.close();
    
    if(bTwoKinects) {
        kinect2.update();
        kinect2.setCameraTiltAngle(0);
        kinect2.close();
    }
    
    kinect1.init(false, false);
    success = kinect1.open(_iLeftKinectId);
    
    while (!success && counter < 10) {
        cout << "Problems found in connecting with Kinect 1. Trying again!" << endl;
        kinect1.close();
        kinect1.init(false, false);
        success = kinect1.open(_iLeftKinectId);
        counter++;
    }
    
    kinect1.setCameraTiltAngle(fKin1Angle);
    cvGrayKin1.allocate(640, 480);
    cvGrayKin1Prev.allocate(640,480);
    
    bKin1Refreshed = false;
    
    //IF USING TWO KINECTS, SETUP KINECT TWO
	
    if(bTwoKinects) {
    
        fKin2Angle = 0;
        
        success = false;
        counter = 0;
        
        kinect2.init(false, false);
        success = kinect2.open(_iRightKinectId);
        
        kinect2.update();
        kinect2.close();
        
        kinect2.init(false, false);
        
        success = kinect2.open(_iRightKinectId);
        
        while (!success && counter < 10) {
            cout << "Problems found in connecting with Kinect 2. Trying again!" << endl;
            kinect2.close();
            kinect2.init(false, false);
            success = kinect2.open(_iRightKinectId);
            counter++;
        }
        
        kinect2.setCameraTiltAngle(fKin2Angle);
        cvGrayKin2.allocate(640, 480);
        cvGrayKin2Prev.allocate(640, 480);
        
        bKinectsStarted = false;
        bKin2Refreshed = false;
        
        vector<ofPoint> allocator(KIN_H * KIN_OUTPUT_W, ofPoint(0,0,0));
        
        for (int i = 0; i < iBufferSize; i++) {
            pointCloudBuffer.push_back(allocator);
        }
        
        allocator.clear();
        
    }
    
    else {
        
        vector<ofPoint> allocator(KIN_H * KIN_W, ofPoint(0,0,0));
        
        for (int i = 0; i < iBufferSize; i++) {
            pointCloudBuffer.push_back(allocator);
        }
        
        allocator.clear();
        
    }
    
    iNearThreshold  = 0;
    iFarThreshold   = 255;
    iMinBlobSize    = 20;
    iMaxBlobSize    = 20000;
    iMaxNumBlobs    = 10;
        
    font.loadFont("Ruda-Regular.ttf", 32); 
}
Example #20
0
 void build_morton(avector<PrimRef>& prims, isa::PrimInfo& pinfo)
 {
   unsigned N = unsigned(pinfo.size());
   /* array for morton builder */
   avector<isa::MortonID32Bit> morton_src(N);
   avector<isa::MortonID32Bit> morton_tmp(N);
   for (unsigned i=0; i<N; i++) 
     morton_src[i].index = i;
   
   /* fast allocator that supports thread local operation */
   FastAllocator allocator(nullptr);
   
   for (size_t i=0; i<2; i++)
   {
     std::cout << "iteration " << i << ": building BVH over " << N << " primitives, " << std::flush;
     double t0 = getSeconds();
     
     allocator.reset();
     
     std::pair<Node*,BBox3fa> node_bounds = isa::bvh_builder_morton<Node*>(
       
       /* thread local allocator for fast allocations */
       [&] () -> FastAllocator::ThreadLocal* { 
         return allocator.threadLocal(); 
       },
       
       BBox3fa(empty),
       
       /* lambda function that allocates BVH nodes */
       [&] ( isa::MortonBuildRecord<Node*>& current, isa::MortonBuildRecord<Node*>* children, size_t N, FastAllocator::ThreadLocal* alloc ) -> InnerNode*
       {
         assert(N <= 2);
         InnerNode* node = new (alloc->malloc(sizeof(InnerNode))) InnerNode;
         *current.parent = node;
         for (size_t i=0; i<N; i++) 
           children[i].parent = &node->children[i];
         return node;
       },
       
       /* lambda function that sets bounds */
       [&] (InnerNode* node, const BBox3fa* bounds, size_t N) -> BBox3fa
       {
         BBox3fa res = empty;
         for (size_t i=0; i<N; i++) {
           const BBox3fa b = bounds[i];
           res.extend(b);
           node->bounds[i] = b;
         }
         return res;
       },
       
       /* lambda function that creates BVH leaves */
       [&]( isa::MortonBuildRecord<Node*>& current, FastAllocator::ThreadLocal* alloc, BBox3fa& box_o) -> Node*
       {
         assert(current.size() == 1);
         const size_t id = morton_src[current.begin].index;
         const BBox3fa bounds = prims[id].bounds(); 
         Node* node = new (alloc->malloc(sizeof(LeafNode))) LeafNode(id,bounds);
         *current.parent = node;
         box_o = bounds;
         return node;
       },
       
       /* lambda that calculates the bounds for some primitive */
       [&] (const isa::MortonID32Bit& morton) -> BBox3fa {
         return prims[morton.index].bounds();
       },
       
       /* progress monitor function */
       [&] (size_t dn) { 
         // throw an exception here to cancel the build operation
       },
       
       morton_src.data(),morton_tmp.data(),prims.size(),2,1024,1,1);
     
     Node* root = node_bounds.first;
     
     double t1 = getSeconds();
     
     std::cout << 1000.0f*(t1-t0) << "ms, " << 1E-6*double(N)/(t1-t0) << " Mprims/s, sah = " << root->sah() << " [DONE]" << std::endl;
   }
 }
Example #21
0
void Vizi3DWorld::load( const std::string& name ) {

    // @see http://code.google.com/p/vjson
    FILE *fp = fopen( name.c_str(), "rb" );
    if ( !fp ) {
        throw "Can't open file '" + name + "'";
    }

    fseek( fp, 0, SEEK_END );
    const auto size = ftell( fp );
    fseek( fp, 0, SEEK_SET );

    block_allocator allocator( 1024 );
    char* source = (char*)allocator.malloc( size + 1 );
    fread( source, 1, size, fp );
    source[size] = 0;

    fclose(fp);

    char *errorPos = 0;
    char *errorDesc = 0;
    int errorLine = 0;
    json_value* root = json_parse(
        source,
        &errorPos, &errorDesc, &errorLine,
        &allocator
    );
    if ( !root ) {
        std::cerr << "Position: " << errorPos << std::endl;
        std::cerr << "Description: " << errorDesc << std::endl;
        std::cerr << "Line: " << errorLine << std::endl;
        throw "File corrupt.";
    }

    // Заполняем структуры из JSON-файла

    //std::cout <<  "Parse json-map:" << std::endl;
    for (json_value* itr = root->first_child; itr; itr = itr->next_sibling) {
        if ( itr->name ) {
            //std::cout << "    " << itr->name << std::endl;
        }

        if ( (std::string)itr->name == "name" ) {
            assert( itr->type == JSON_STRING );
            mAbout.name = (std::string)itr->string_value;
            continue;
        }

        if ( (std::string)itr->name == "scale" ) {
            assert( (itr->type == JSON_FLOAT) || (itr->type == JSON_INT) );
            mAbout.scale = (itr->type == JSON_FLOAT) ? itr->float_value : (float)itr->int_value;
            continue;
        }

        if ( (std::string)itr->name == "path-to-image" ) {
            assert( itr->type == JSON_OBJECT );
            for (json_value* child = itr->first_child; child; child = child->next_sibling) {
                assert( child->type == JSON_STRING );
                mAbout.pathToImage[ (std::string)child->name ] = (std::string)child->string_value;
            }
            assert( (mAbout.pathToImage.find( "form" ) != mAbout.pathToImage.cend())
                && (mAbout.pathToImage.find( "material" ) != mAbout.pathToImage.cend())
                && "Ждём как минимум путь к формам и материалам." );
            continue;
        }

        if ( boost::starts_with( (std::string)itr->name, "map-" ) ) {
            assert( itr->type == JSON_OBJECT );
            // В этом ключе хранится и название участка карты
            const std::string tinyMapName = parseTinyMapName( (std::string)itr->name);
            auto tm = mAbout.tinyMap.find( tinyMapName );
            assert( (tm == mAbout.tinyMap.cend()) && "Каждый участок карты должен обладать уникальным именем." );
            assert( (mAbout.scale > 0.0f) && "Масштаб 'scale' должен быть определён и определён до 'map-'." );
            mAbout.tinyMap[ tinyMapName ] = parseTinyMap( itr, mAbout.scale );
            continue;
        }

        if ( (std::string)itr->name == "note" ) {
            assert( itr->type == JSON_OBJECT );
            mAbout.noteMap = parseNoteMap( itr );
            continue;
        }

        /* - @example http://code.google.com/p/vjson
        switch ( itr->type ) {
            case JSON_ARRAY:
                printf( "start array\n" );
                break;
            case JSON_BOOL:
                printf(itr->int_value ? "true\n" : "false\n");
                break;
            case JSON_INT:
                printf("%d\n", itr->int_value);
                break;
            case JSON_FLOAT:
                printf("%f\n", itr->float_value);
                break;
            case JSON_NULL:
                printf("null\n");
                break;
            case JSON_OBJECT:
                printf( "start object\n" );
                break;
            case JSON_STRING:
                printf("\"%s\"\n", itr->string_value);
                break;
        }
        */
    }


    // Если в файле не декларирован пустой элемент (пробел),
    // исправляем это
    if ( mAbout.noteMap.find( ' ' ) == mAbout.noteMap.cend() ) {
        mAbout.noteMap[' '] = noteElement_t();
    }


    // Подготавливаем битовые образы для оптимизации отрисовки карты
    prepareVisualBitImage();


    // Инициализируем указатель для отрисовки
    drawItr = cbegin();
}
Example #22
0
omrobjectptr_t
OMR_GC_AllocateObject(OMR_VMThread * omrVMThread, uintptr_t allocationCategory, uintptr_t requiredSizeInBytes, uintptr_t allocationFlags)
{
	MM_AllocateInitialization allocator(MM_EnvironmentBase::getEnvironment(omrVMThread), allocationCategory, requiredSizeInBytes, allocationFlags);
	return OMR_GC_AllocateObject(omrVMThread, &allocator);
}
Example #23
0
 void printAllocator() {
     log() << "allocator: " << allocator() << endl;
 }
Example #24
0
void MultiplePoolTestTask( int tid, std::mutex& coutmtx)
{
	std::stringstream ss;
	ss << "multiple_pool_threaded_custom_" << tid << ".csv";

	std::fstream file;
	file.open(ss.str(), std::ios_base::trunc | std::ios_base::out);
	
	PoolTestWriteCaptions(file);

	PoolAllocator allocator(sizeof(Particle), POOL_TEST_THREADED_PARTICLE_COUNT);

	// Setup particle list and free-index list.
	size_t freeList[POOL_TEST_THREADED_PARTICLE_COUNT];
	Particle* particles[POOL_TEST_THREADED_PARTICLE_COUNT];

	for(unsigned i = 0; i < POOL_TEST_THREADED_PARTICLE_COUNT; ++i)
		freeList[i] = i;

	int freeListIndex = POOL_TEST_THREADED_PARTICLE_COUNT - 1;

	Timer timer;
	int frameCount = 0;
	double totalTime = 0.0;
	double minTime = +100000000.0;
	double maxTime = -100000000.0;

	// Start the simulation
	bool running = true;
	while (running)
	{
		int creations = 0;
		int deletions = 0;

		timer.Start();

		// Allocate particle objects
		while (frameCount < POOL_TEST_THREADED_SPAWN_FRAME_LIMIT && freeListIndex != -1)
		{
			creations++;

			int lifetime = RNDThreaded[freeList[freeListIndex]];
			Particle* p = new(allocator.Alloc()) Particle(lifetime);
			
			particles[freeList[freeListIndex--]] = p;
		}

		// Update simulation of particles (increase lived time)
		// Deallocate dead particle objects.
		for (size_t i = 0; i < POOL_TEST_THREADED_PARTICLE_COUNT; ++i)
		{
			Particle*& particle = particles[i];

			if(particle != nullptr)
			{
				particle->framesLeftToLive--;

				if (particle->framesLeftToLive <= 0)
				{
					deletions++;

					allocator.Free(particle);

					particle = nullptr;
					freeList[++freeListIndex] = i;
				}
			}
		}

		// Check if all are dead and terminate.
		running = (freeListIndex != POOL_TEST_THREADED_PARTICLE_COUNT - 1)  || (frameCount < POOL_TEST_THREADED_SPAWN_FRAME_LIMIT);

		double elapsed = timer.Stop();
		frameCount++;
		totalTime += elapsed;

		if (elapsed < minTime)
			minTime = elapsed;
		if (elapsed > maxTime)
			maxTime = elapsed;

		PoolTestWriteFrameData(file, frameCount, elapsed, creations, deletions, creations * sizeof(Particle));
	}

	std::lock_guard<std::mutex> lock(coutmtx);
	std::cout << "Thread " << tid << std::endl;
	std::cout << "\tFrames Simulated: " << frameCount << std::endl;
	std::cout << "\tTotal Experiment Time: " << totalTime << std::endl;
	std::cout << "\tAverage Frame Time: " << totalTime / frameCount << std::endl;
	std::cout << "\tMin Frame Time: " << minTime << std::endl;
	std::cout << "\tMax Frame Time: " << maxTime << std::endl;
}
void MemoryDealer::deallocate(size_t offset)
{
    allocator()->deallocate(offset);
}
Example #26
0
 * Author Kucheruavyu Ilya ([email protected])
 * 2014 Ukraine Kharkiv
 *  _         _ _ _
 * | |       (_|_) |
 * | | _____  _ _| |__   __ _
 * | |/ / _ \| | | '_ \ / _` |
 * |   < (_) | | | |_) | (_| |
 * |_|\_\___/| |_|_.__/ \__,_|
 *          _/ |
 *         |__/
 **/

#include "RClassNamePair.h"

constructor(RClassNamePair)) {
    object = allocator(RClassNamePair);

    if (object != nil) {
        master(object, RString) = allocator(RString);
        if(master(object, RString) != nil) {
            // 2 - it's for RClassNamePair
            object->classId = 2;
            object->idForClassName = 0;
        }
    }
    return object;
}

destructor(RClassNamePair) {
    deallocator(master(object, RString));
}
Example #27
0
void readimage_grey(char* filename, void* allocator(size_t), struct IMAGE_FORMAT_GREY* imageinfo)
{
	unsigned char buf[1024];
	FILE* fh;
	size_t r;
	unsigned int x,y;
	unsigned int image_size;
	unsigned int maxval;
	unsigned int memory_width;

    fh = fopen(filename, "rb");
	if (!fh)
	{
		printf("Failed to open file %s\n", filename);
		exit(-1);
	}

	r = fread(buf, 1, 2, fh);
	if (r != 2)
	{
		fclose(fh);
		printf("Failed to read data from file\n");
		exit(-1);
	}
	if (buf[0] != 'P' || buf[1] != '6')
	{
		fclose(fh);
		printf("File format is not P6, which is the only supported format\n");
		exit(-1);
	}

	do
	{
		if (fscanf(fh, "%s", buf) == 0)
		{
			fclose(fh);
			printf("Failed to detect image size\n");
			exit(-1);
		}
	} while(fscanf(fh, "%d %d\n%d", &imageinfo->width, &imageinfo->height, &maxval) != 3);

	//Read whitespace
	fscanf(fh, " ");
	image_size = imageinfo->width * imageinfo->height;
	memory_width = imageinfo->width + ((128 - imageinfo->width) % 128);

	imageinfo->image = (unsigned char*)allocator(memory_width * imageinfo->height * sizeof(unsigned char));
		
	for(y = 0; y < imageinfo->height; y++)
	{
		for(x = 0; x < imageinfo->width; x++)
		{
			r = fread(buf, 1, 3, fh);
			if (r != 3)
			{
				fclose(fh);
				printf("Failed to read image data at (x,y): (%d,%d)\n", x, y);
				exit(-1);
			}
	
			//Brightness from RGB
			//Perhaps use: (0.299 * buf[0]) + (0.587 * buf[1]) + (0.114 * buf[2])
			//or (buf[0] + buf[1] + buf[2]) / 3;
	
			imageinfo->image[(y*memory_width)+x] = (buf[0] + buf[1] + buf[2]) / 3;
		}
		
	}
	fclose(fh);
}
Example #28
0
    }
    return (RayMethodType) (result);
}

const char* RayMethodTypeToString(RayMethodType type) {
    if(type < MethodTypesCount) {
        return methodTypesConsts[type];
    } else {
        return nil;
    }
}

#pragma mark Constructor - Destructor - Method

constructor(RayMethod), RayMethodType type, size_t returnType) {
    object = allocator(RayMethod);
    if(object != nil) {
        if((object->arguments = makeRArray()) != nil) {

            object->arguments->destructorDelegate = RClassNamePairDeleter;
            object->arguments->printerDelegate    = (PrinterDelegate) p(RClassNamePair);

            object->classId = registerClassOnce(toString(RayMethod));
            object->methodType = type;
            object->returnType = returnType;
            object->nativeName = nil;
            object->namespaceName = nil;
        }

    }
    return object;
Example #29
0
Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
{
	/* streams of pixels (a, r, g, b channels)
	 *
	 * stored in separated stream so data are always aligned on 4B boundary */
	Colour *dst_px_orig[ZOOM_LVL_COUNT];

	/* interleaved stream of 'm' channel and 'n' channel
	 * 'n' is number of following pixels with the same alpha channel class
	 * there are 3 classes: 0, 255, others
	 *
	 * it has to be stored in one stream so fewer registers are used -
	 * x86 has problems with register allocation even with this solution */
	uint16 *dst_n_orig[ZOOM_LVL_COUNT];

	/* lengths of streams */
	uint32 lengths[ZOOM_LVL_COUNT][2];

	ZoomLevel zoom_min;
	ZoomLevel zoom_max;

	if (sprite->type == ST_FONT) {
		zoom_min = ZOOM_LVL_NORMAL;
		zoom_max = ZOOM_LVL_NORMAL;
	} else {
		zoom_min = _settings_client.gui.zoom_min;
		zoom_max = _settings_client.gui.zoom_max;
		if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
	}

	for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
		const SpriteLoader::Sprite *src_orig = &sprite[z];

		uint size = src_orig->height * src_orig->width;

		dst_px_orig[z] = CallocT<Colour>(size + src_orig->height * 2);
		dst_n_orig[z]  = CallocT<uint16>(size * 2 + src_orig->height * 4 * 2);

		uint32 *dst_px_ln = (uint32 *)dst_px_orig[z];
		uint32 *dst_n_ln  = (uint32 *)dst_n_orig[z];

		const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *)src_orig->data;

		for (uint y = src_orig->height; y > 0; y--) {
			Colour *dst_px = (Colour *)(dst_px_ln + 1);
			uint16 *dst_n = (uint16 *)(dst_n_ln + 1);

			uint16 *dst_len = dst_n++;

			uint last = 3;
			int len = 0;

			for (uint x = src_orig->width; x > 0; x--) {
				uint8 a = src->a;
				uint t = a > 0 && a < 255 ? 1 : a;

				if (last != t || len == 65535) {
					if (last != 3) {
						*dst_len = len;
						dst_len = dst_n++;
					}
					len = 0;
				}

				last = t;
				len++;

				if (a != 0) {
					dst_px->a = a;
					*dst_n = src->m;
					if (src->m != 0) {
						/* Get brightest value */
						uint8 rgb_max = max(src->r, max(src->g, src->b));

						/* Black pixel (8bpp or old 32bpp image), so use default value */
						if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS;
						*dst_n |= rgb_max << 8;

						/* Pre-convert the mapping channel to a RGB value */
						Colour colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), rgb_max);
						dst_px->r = colour.r;
						dst_px->g = colour.g;
						dst_px->b = colour.b;
					} else {
						dst_px->r = src->r;
						dst_px->g = src->g;
						dst_px->b = src->b;
					}
					dst_px++;
					dst_n++;
				} else if (len == 1) {
					dst_px++;
					*dst_n = src->m;
					dst_n++;
				}

				src++;
			}

			if (last != 3) {
				*dst_len = len;
			}

			dst_px = (Colour *)AlignPtr(dst_px, 4);
			dst_n  = (uint16 *)AlignPtr(dst_n, 4);

			*dst_px_ln = (uint8 *)dst_px - (uint8 *)dst_px_ln;
			*dst_n_ln  = (uint8 *)dst_n  - (uint8 *)dst_n_ln;

			dst_px_ln = (uint32 *)dst_px;
			dst_n_ln =  (uint32 *)dst_n;
		}

		lengths[z][0] = (byte *)dst_px_ln - (byte *)dst_px_orig[z]; // all are aligned to 4B boundary
		lengths[z][1] = (byte *)dst_n_ln  - (byte *)dst_n_orig[z];
	}

	uint len = 0; // total length of data
	for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
		len += lengths[z][0] + lengths[z][1];
	}

	Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len);

	dest_sprite->height = sprite->height;
	dest_sprite->width  = sprite->width;
	dest_sprite->x_offs = sprite->x_offs;
	dest_sprite->y_offs = sprite->y_offs;

	SpriteData *dst = (SpriteData *)dest_sprite->data;
	memset(dst, 0, sizeof(*dst));

	for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
		dst->offset[z][0] = z == zoom_min ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1];
		dst->offset[z][1] = lengths[z][0] + dst->offset[z][0];

		memcpy(dst->data + dst->offset[z][0], dst_px_orig[z], lengths[z][0]);
		memcpy(dst->data + dst->offset[z][1], dst_n_orig[z],  lengths[z][1]);

		free(dst_px_orig[z]);
		free(dst_n_orig[z]);
	}

	return dest_sprite;
}
TEST(MemoryAllocator, init) {
  MemoryAllocator allocator({MemorySectionDefinition("text", 4, 2),
                             MemorySectionDefinition("data", 16)});
}