CL_CollisionOutline::CL_CollisionOutline(
	CL_IODevice &file, const CL_String &file_extension,
	int alpha_limit,
	CL_OutlineAccuracy accuracy,
	bool get_insides)
{
	if( file_extension == "out" )
	{
		CL_SharedPtr<CL_CollisionOutline_Generic> new_impl(new CL_CollisionOutline_Generic( new CL_OutlineProviderFile(file), accuracy_raw ));
		impl = new_impl;
	}
	else
	{

		CL_PixelBuffer pbuf = CL_ImageProviderFactory::load(file, file_extension);
	
		if( pbuf.get_format() == cl_rgba8 )
		{
			CL_SharedPtr<CL_CollisionOutline_Generic> new_impl(new CL_CollisionOutline_Generic( new CL_OutlineProviderBitmap(pbuf, alpha_limit, get_insides), accuracy));
			impl = new_impl;
		}
		else
		{
			CL_SharedPtr<CL_CollisionOutline_Generic> new_impl(new CL_CollisionOutline_Generic( new CL_OutlineProviderBitmap(pbuf, alpha_limit, get_insides), accuracy_raw));
			impl = new_impl;
		}
	}

	set_rotation_hotspot(origin_center);
}
  CL_PixelBuffer get_pixelbuffer() const
  {
    if (buffer)
      {
        return buffer;
      }
    else
      {
        // FIXME: ClanLibs indexed handling seems broken, so we do
        // the conversion ourself
        const CL_Palette& palette = NetPanzerData::instance()->get_palette();
        unsigned char* data = NetPanzerData::instance()->get_tiledata() + (32*32) * id;
        buffer = CL_PixelBuffer(32, 32, 32*3, CL_PixelFormat::rgb888);

        buffer.lock();
        unsigned char* target = static_cast<unsigned char*>(buffer.get_data());

        for(int i = 0; i < 32*32; ++i)
          {
            target[3*i+0] = palette[data[i]].get_blue();
            target[3*i+1] = palette[data[i]].get_green();
            target[3*i+2] = palette[data[i]].get_red();
          }
        buffer.unlock();
                
        return buffer;
      }
  }
void CL_PixelCanvas::draw_pixels_bicubic(int x, int y, int zoom_number, int zoom_denominator, const CL_PixelBuffer &image)
{
	if (image.get_format() == cl_argb8)
	{
		pipeline->queue(new(pipeline.get()) CL_PixelCommandBicubic(x, y, zoom_number, zoom_denominator, image));
		pipeline->wait_for_workers();
	}
	else
	{
		CL_PixelBuffer image_argb8 = image.to_format(cl_argb8);
		draw_pixels_bicubic(x, y, zoom_number, zoom_denominator, image_argb8);
	}
}
void CL_PixelCanvas::draw_pixels(const CL_Rect &dest, const CL_PixelBuffer &image, const CL_Rect &src_rect, const CL_Colorf &primary_color)
{
	if (image.get_format() == cl_argb8)
	{
		pipeline->queue(new(pipeline.get()) CL_PixelCommandPixels(dest, image, src_rect, primary_color));
		pipeline->wait_for_workers();
	}
	else
	{
		CL_PixelBuffer image_argb8 = image.to_format(cl_argb8);
		draw_pixels(dest, image_argb8, src_rect, primary_color);
	}
}
Beispiel #5
0
CL_Color
Tile::calc_color()
{
  CL_PixelBuffer buffer = get_pixelbuffer();
  buffer.lock();
  unsigned char* buf = static_cast<unsigned char*>(buffer.get_data());
  int len = buffer.get_height() * buffer.get_width();

  int red   = 0;
  int green = 0;
  int blue  = 0;
  int alpha = 0;
  
  switch (buffer.get_format().get_depth())
  {
    case 8:
    {
      CL_Palette palette = buffer.get_palette();
      for(int i = 0; i < len; ++i)
      {
        red   += palette.colors[buf[i]].get_red();
        green += palette.colors[buf[i]].get_green();
        blue  += palette.colors[buf[i]].get_blue();
        alpha += 255;
      }
    }
    break;
    case 24:
      for(int i = 0; i < len; ++i)
      {
        red   += buf[3*i + 0];
        green += buf[3*i + 1];
        blue  += buf[3*i + 2];
        alpha += 255;
      }
      break;
    case 32:
      for(int i = 0; i < len; ++i)
      {
        int a = buf[4*i + 0];
        alpha += a;
        red   += buf[4*i + 3]*a/255;;
        green += buf[4*i + 2]*a/255;;
        blue  += buf[4*i + 1]*a/255;;
      }
      break;
  }

  buffer.unlock();

  return CL_Color(static_cast<int>(red   / len),
                  static_cast<int>(green / len),
                  static_cast<int>(blue  / len),
                  static_cast<int>(alpha / len));
}
Beispiel #6
0
void BitMask::init(const CL_PixelBuffer& pixBuf) {
    if (!bitStore_) {
        width_ = pixBuf.get_width();
        height_ = pixBuf.get_height();
        bitStoreSize_ = ((width_ * height_) / 8) + 1;
        bitStore_ = reinterpret_cast<uint8_t*>(malloc(bitStoreSize_));
        memset(bitStore_, 0, bitStoreSize_);

        const uint32_t* bufPtr = reinterpret_cast<const uint32_t*>(pixBuf.get_data());

        for (unsigned int y = 0; y < height_; ++y) {
            for (unsigned int x = 0; x < width_; ++x) {
                if (*bufPtr & 0x000000FFu) { // alpha != 0
                    setPixel(x, y);
                }
                ++bufPtr;
            }
        }
    }
}
Beispiel #7
0
//ф-ция проверки на наличие прозрачных пикселей
bool testAlpha(CL_PixelBuffer &image)
{
	int width = image.get_width();
	int height = image.get_height();
	int pitch = image.get_pitch();
	unsigned char *row = static_cast<unsigned char *>(image.get_data());
	for (int y = 0; y < height; ++y, row += pitch)
	{
		unsigned char *pixel = row;
		for (int x = 0; x < width; ++x, pixel += 4)
		{
			//pixel[0]; //alpha
			//pixel[1]; //blue
			//pixel[2]; //green
			//pixel[3]; //red
			if (pixel[0] < ALPHA_LIMIT)
				return false;
		}
	}
	return true;
}
Beispiel #8
0
//сохранение данных о коллизии в файл
void saveCollision(CL_PixelBuffer &image, CL_File file)
{
	int width = image.get_width();
	int height = image.get_height();
	int pitch = image.get_pitch();

	std::vector<unsigned char> collusionBits((width+7)/8*height, 0);

	unsigned char *row = static_cast<unsigned char *>(image.get_data());
	for (int y = 0; y < height; ++y, row += pitch)
	{
		unsigned char *pixel = row;
		for (int x = 0; x < width; ++x, pixel += 4)
		{
			if (pixel[0] <= 255 - ALPHA_LIMIT)
			{
				//номер байта
				int i = y*(width/8) + x/8;
				//CL_Console::write_line("$$ x= %1 y= %2 -> i= %3 ", x, y, i);
				//установка бита смещения
				collusionBits[i] |= 1<<(7 - x%8);
			}
		}
	}

	//сохранение в файл сигнатуры
	file.write_uint32(0x4D534442);
	//сохранение в файл ширины спрайта
	file.write_uint32(width);
	//сохранение в файл высоты спрайта
	file.write_uint32(height);

	//сохранение в файл массива
	for(std::vector<unsigned char>::const_iterator iterCollusionBits = collusionBits.begin(); iterCollusionBits != collusionBits.end(); ++iterCollusionBits)
		file.write_uint8(*iterCollusionBits);
}
CL_CollisionOutline::CL_CollisionOutline(
	const CL_PixelBuffer &pbuf,
	int alpha_limit,
	CL_OutlineAccuracy accuracy)
 : impl(new CL_CollisionOutline_Generic())
{
	if( pbuf.get_format() == cl_rgba8 )
	{
		CL_SharedPtr<CL_CollisionOutline_Generic> new_impl(new CL_CollisionOutline_Generic( new CL_OutlineProviderBitmap(pbuf, alpha_limit), accuracy));
		impl = new_impl;
	}
	else
	{
		CL_SharedPtr<CL_CollisionOutline_Generic> new_impl(new CL_CollisionOutline_Generic( new CL_OutlineProviderBitmap(pbuf, alpha_limit), accuracy_raw));
		impl = new_impl;
	}
	
	set_rotation_hotspot(origin_center);
}
void
Screenshot::write_screenshot_pnm(const std::string& filename)
{
  CL_PixelBuffer buf = take_screen_shot();

  FILE* out = fopen(filename.c_str(), "wb");
  
  if (!out)
    {
      perror(filename.c_str());
      std::cout << "Screenshot: Couldn't write file: " << filename << std::endl;
      return;
    }

  buf.lock();
  int width  = buf.get_width();
  int pitch  = buf.get_width()*3;
  int height = buf.get_height();

  fprintf(out,
	  "P6\n"
	  "# CREATOR: Feuerkraft\n"
          "%d %d\n"
	  "255\n",
	  width,
	  height);

  unsigned char* data = static_cast<unsigned char*>(buf.get_data());
  
  for(int i = height-1; i >= 0; --i)
    {
      fwrite(data + pitch*i,
             sizeof(unsigned char),
             pitch, 
             out);
    }

  buf.unlock();
  fclose(out);
}
void CL_ListViewIcon::draw(CL_GraphicContext &gc, const CL_Rect &rect, CL_ListViewDisplayMode mode, const CL_Colorf &color)
{
	CL_Sprite sp = get_sprite(mode);
	if (!sp.is_null())
	{
		float scale = 1.0;

		sp.set_color(color);
		//		if (mode == listview_mode_thumbnails && sp.get_frame_size(0) != rect.get_size())
		if (impl->scalable && (sp.get_frame_size(0) != rect.get_size()))
		{
			// Scale to max vertically or horizontally.
			float sx, sy;
			sx = rect.get_width()/float(sp.get_width());
			sy = rect.get_height()/(float)sp.get_height();
			if (sx <= 0 || sy <= 0)
			{
				return;
			}
			scale = cl_min(sx, sy);
			sp.set_scale(scale,scale);
		}

		CL_Rect R = rect;
		CL_Point offset = get_offset(mode);

		R.translate(offset);

		if (!impl->scalable && offset == CL_Point(0,0))
		{
			// center in cell rect.
			int center_offset_x = int((float)rect.get_center().x - (float)rect.left - scale*(float)sp.get_width()/2.0); 
			int center_offset_y = int((float)rect.get_center().y - (float)rect.top - scale*(float)sp.get_height()/2.0); 
			R.left += center_offset_x;
			R.top += center_offset_y;
		}

		if (!impl->scalable)
			sp.draw(gc, (float)R.left, (float)R.top);
		else
			sp.draw(gc, R);

		return;
	}

	CL_PixelBuffer pb = get_pixel_buffer(mode);
	if (!pb.is_null())
	{
		float scale = 1.0;
		float center_offset_x = 0, center_offset_y = 0;

//		if (mode == listview_mode_thumbnails && pb.get_size() != rect.get_size())
		if (impl->scalable && (pb.get_size() != rect.get_size()))
		{
			float sx = 1.0, sy = 1.0;

			// Scale to max vertically or horizontally.
			sx = rect.get_width()/float(pb.get_width());
			sy = rect.get_height()/(float)pb.get_height();
			if (sx <= 0 || sy <= 0)
			{
				return;
			}

			scale = cl_min(sx, sy);

			// center in the rect.
			center_offset_x = (float)rect.get_center().x - (float)rect.left - scale*(float)pb.get_width()/2.0f; 
			center_offset_y = (float)rect.get_center().y - (float)rect.top - scale*(float)pb.get_height()/2.0f; 
		}

		CL_Point offset = get_offset(mode);

		gc.draw_pixels(rect.left + center_offset_x + offset.x, rect.top + center_offset_y + offset.y, scale, scale, pb, pb.get_size(), color);
	}
}
void CL_Texture::set_image(
	CL_PixelBuffer &image,
	int level,
	int border,
	int format)
{
	CLenum native_format = 0, native_type = 0;
	bool is_native_format = CL_OpenGL::to_opengl_pixelformat(image.get_format(), native_format, native_type);
	if (is_native_format)
	{
		switch (impl->target)
		{
/*		case CL_TEXTURE_3D:
			image.lock();
			set_image3d_gl(
				impl->target,
				level,
				(format == 0) ? native_format : format,
				image.get_width(),
				image.get_height(),
				image.get_depth(),
				border,
				native_format,
				native_type,
				image.get_data());
			image.unlock();
			break;
*/
		case CL_TEXTURE_2D:
			image.lock();
			set_image2d_gl(
				impl->target,
				level,
				(format == 0) ? native_format : format,
				image.get_width(),
				image.get_height(),
				border,
				native_format,
				native_type,
				image.get_data());
			image.unlock();
			break;

		case CL_TEXTURE_1D:
			image.lock();
			set_image1d_gl(
				impl->target,
				level,
				(format == 0) ? native_format : format,
				image.get_width(),
				border,
				native_format,
				native_type,
				image.get_data());
			image.unlock();
			break;

		default:
			throw CL_Error("CL_Texture::set_image does not support this texture format");
		}
	}
	else
	{
		// For now, upload all non-opengl compatible formats in rgba8888 format:
		
		CL_PixelBuffer gl_image = image.to_format(CL_PixelFormat::rgba8888);
		set_image(gl_image, format, level, border);
	}
}
void CL_PNGProvider::save(CL_PixelBuffer buffer, CL_IODevice &iodev)
{
	if (buffer.get_format() != cl_abgr8)
	{
		CL_PixelBuffer newbuf(
			buffer.get_width(),
			buffer.get_height(), 
			cl_abgr8);
		buffer.convert(newbuf);
		buffer = newbuf;
	}

	png_structp png_ptr;
	png_infop info_ptr;

	png_ptr  = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	info_ptr = png_create_info_struct(png_ptr);

	png_set_read_fn(png_ptr, &iodev, &CustomIOFunctions::read);
	png_set_write_fn(png_ptr, &iodev, &CustomIOFunctions::write, CustomIOFunctions::flush);

	#ifndef PNG_COLOR_TYPE_RGBA
	#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
	#endif

	png_set_IHDR(
		png_ptr, info_ptr, 
		buffer.get_width(), buffer.get_height(), 8 /* bitdepth */,
		PNG_COLOR_TYPE_RGBA,
		PNG_INTERLACE_NONE, 
		PNG_COMPRESSION_TYPE_BASE, 
		PNG_FILTER_TYPE_BASE);

	png_write_info(png_ptr, info_ptr);

	png_uint_32 height = buffer.get_height();
	png_uint_32 row_bytes = buffer.get_width()*4;

	png_byte* image = new png_byte[height * row_bytes];
	png_bytep* row_pointers = new png_bytep[height];

	// fill the image with data
	for (int i = 0; i < buffer.get_width()*buffer.get_height()*4; ++i)
		image[i] = static_cast<unsigned char*>(buffer.get_data())[i];

	// generate row pointers
	for (unsigned int k = 0; k < height; k++)
		row_pointers[k] = image + (k * row_bytes);

	png_write_image(png_ptr, row_pointers);

	png_write_end(png_ptr, info_ptr);

	png_destroy_write_struct( &png_ptr, &info_ptr );

	delete[] image;
	delete[] row_pointers;
}
Beispiel #14
0
CL_Image HTMLPage::load_image(CL_GraphicContext &gc, const CL_String &image_url)
{
	HTMLUrl url(image_url, pageurl);
	CL_Console::write_line("Downloading image: %1", url.to_string());
	CL_String8 request;
	request = cl_format("GET %1 HTTP/1.1\r\n", url.path+url.query);
	request += cl_format("Host: %1\r\nConnection: close\r\nReferer: %2\r\nAccept: image/png, image/jpeg\r\nUser-Agent: CSSTokenize/0.1\r\n\r\n", url.host, pageurl.to_string());

	CL_TCPConnection connection(CL_SocketName(url.host, url.port));
	connection.set_nodelay(true);
	connection.send(request.data(), request.length(), true);

	CL_String response;
	while (connection.get_read_event().wait(15000))
	{
		char buffer[16*1024];
		int received = connection.read(buffer, 16*1024, false);
		if (received == 0)
			break;
		response.append(buffer, received);
	}
	connection.disconnect_graceful();

	CL_String response_header = response.substr(0, response.find("\r\n\r\n"));
	CL_String content = response.substr(response_header.length() + 4);

	if (response_header.find("Transfer-Encoding: chunked") != CL_String::npos)
	{
		CL_String::size_type start = 0;
		while (true)
		{
			CL_String::size_type end = content.find("\r\n", start);
			if (end == CL_String::npos)
				end = content.length();

			CL_String str_length = content.substr(start, end-start);
			int length = CL_StringHelp::text_to_int(str_length, 16);
			content = content.substr(0, start) + content.substr(end+2);
			start += length;


			end = content.find("\r\n", start);
			if (end == CL_String::npos)
				end = content.length();
			content = content.substr(0, start) + content.substr(end+2);

			if (length == 0)
				break;
		}
	}

	CL_DataBuffer buffer(content.data(), content.length());
	CL_IODevice_Memory device(buffer);
	if (response_header.find("image/png") != CL_String::npos)
	{
		CL_PixelBuffer pb = CL_PNGProvider::load(device);
		return CL_Image(gc, pb, pb.get_size());
	}
	else if (response_header.find("image/jpeg") != CL_String::npos)
	{
		CL_PixelBuffer pb = CL_JPEGProvider::load(device);
		return CL_Image(gc, pb, pb.get_size());
	}
	else if (response_header.find("image/gif") != CL_String::npos)
	{
		CL_PixelBuffer pb = GIFProvider::load(device);
		return CL_Image(gc, pb, pb.get_size());
	}
	else
	{
		CL_Console::write_line("Unknown image type: %1", CL_String8(buffer.get_data(), buffer.get_size()));
		return CL_Image();
	}
}
/** Returns a pointer to a new image, based on 'surface'
    but with changed hue. Changing the hue means to "rotate"
    the color spectrum. You can read more about the HSV color
    model on the Internet.
    This method is used to change the color of a sprite
    (e.g. a car or another object). I suggest to make the
    basic images in a red color-spectrum and create all
    other colors from it.
    For examples, please visit the Trophy homepage developer
    corner (http://trophy.sourceforge.net)
    \param hue Changing of hue: 0-360
    \param saturation Changing of saturation: -100...100
    \param value Changing of value (Color intensity): -100...100
*/
CL_PixelBuffer
CAImageManipulation::changeHSV( CL_PixelBuffer pixBufOriginal,
                                int hue, int saturation, int value )
{
    CL_PixelBuffer pixbuf(pixBufOriginal.get_width(), pixBufOriginal.get_height(), pixBufOriginal.get_format());
    pixBufOriginal.convert(pixbuf);

    CL_TextureFormat pf = pixbuf.get_format();
    // Check that we handle this pixel format
    if(pf != CL_TextureFormat::cl_rgba8 && pf != CL_TextureFormat::cl_rgb8 &&
            pf != CL_TextureFormat::cl_rgba4 )
    {
        std::cout << "Unknow pixel format !" << pf << std::endl;
        return pixBufOriginal.copy();
    }

    // Calc size in bytes:
    //
    int bpp = pixBufOriginal.get_bytes_per_pixel();
    int size = pixbuf.get_width() * pixbuf.get_height() * bpp;

    pixbuf.lock(CL_BufferAccess::cl_access_read_write);

    unsigned char *data = (unsigned char*)pixbuf.get_data();

    // Change hue:
    //
    int r, g, b, a(0);
    int h, s, v;

    for(int i=0; i<size; i+=bpp )
    {
        if(pf == CL_TextureFormat::cl_rgba8)
        {
            a = data[i];
            b = data[i+1];
            g = data[i+2];
            r = data[i+3];
        } else if (pf == CL_TextureFormat::cl_rgb8)
        {
            std::cout << "TextureFormat : rgb888\n";
            b = data[i];
            g = data[i+1];
            r = data[i+2];
        } else if (pf == CL_TextureFormat::cl_rgba4)
        {
            std::cout << "TextureFormat : rgba4444\n";
            r = data[i] && 0x0F;
            g = (data[i] && 0xF0) >> 4;
            b = data[i+1] && 0x0F;
            a = (data[i+1] && 0xF0) >> 4;
        }

        if( a!=0 && (r!=g || r!=b || g!=b) ) 
        {
            rgbToHsv( r, g, b, &h, &s, &v );

            h += hue;
            s += saturation;
            v += value;
            if( h > 360 ) h -= 360;
            if( s > 255 ) s = 255;
            if( v > 255 ) v = 255;
            if( h < 0 ) h += 360;
            if( s < 0 ) s = 0;
            if( v < 0 ) v = 0;

            hsvToRgb( h, s, v, &r, &g, &b );

            if(pf == CL_TextureFormat::cl_rgba8)
            {
                data[i] = a;
                data[i+1] = b;
                data[i+2] = g;
                data[i+3] = r;
            } else if (pf == CL_TextureFormat::cl_rgb8)
            {
                data[i] = b;
                data[i+1] = g;
                data[i+2] = r;
            } else if (pf == CL_TextureFormat::cl_rgba4)
            {
                data[i] = r + (g << 4);
                data[i+1] = b + (a << 4);
            }
        }
    }