Example #1
0
/* byte to byte pixels, input and output 4-channel RGBA */
void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
                               int profile_to, int profile_from, bool predivide,
                               int width, int height, int stride_to, int stride_from)
{
	float tmp[4];
	int x, y;

	/* we need valid profiles */
	BLI_assert(profile_to != IB_PROFILE_NONE);
	BLI_assert(profile_from != IB_PROFILE_NONE);

	/* always RGBA input */
	for (y = 0; y < height; y++) {
		const uchar *from = rect_from + stride_from * y * 4;
		uchar *to = rect_to + stride_to * y * 4;

		if (profile_to == profile_from) {
			/* same profile, copy */
			memcpy(to, from, sizeof(uchar) * 4 * width);
		}
		else if (profile_to == IB_PROFILE_LINEAR_RGB) {
			/* convert to sRGB to linear */
			if (predivide) {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					srgb_to_linearrgb_predivide_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
			else {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					srgb_to_linearrgb_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
		}
		else if (profile_to == IB_PROFILE_SRGB) {
			/* convert from linear to sRGB */
			if (predivide) {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					linearrgb_to_srgb_predivide_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
			else {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					linearrgb_to_srgb_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
		}
	}
}
Example #2
0
void blf_draw_buffer__start(FontBLF *font)
{
	FontBufInfoBLF *buf_info = &font->buf_info;

	buf_info->col_char[0] = buf_info->col_init[0] * 255;
	buf_info->col_char[1] = buf_info->col_init[1] * 255;
	buf_info->col_char[2] = buf_info->col_init[2] * 255;
	buf_info->col_char[3] = buf_info->col_init[3] * 255;

	if (buf_info->display) {
		copy_v4_v4(buf_info->col_float, buf_info->col_init);
		IMB_colormanagement_display_to_scene_linear_v3(buf_info->col_float, buf_info->display);
	}
	else {
		srgb_to_linearrgb_v4(buf_info->col_float, buf_info->col_init);
	}
}
Example #3
0
/* Sanity checks are done by BLF_draw_buffer() */
void blf_font_buffer(FontBLF *font, const char *str)
{
	unsigned int c;
	GlyphBLF *g, *g_prev = NULL;
	FT_Vector delta;
	int pen_x = (int)font->pos[0], pen_y = 0;
	size_t i = 0;
	GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;

	/* buffer specific vars */
	FontBufInfoBLF *buf_info = &font->buf_info;
	float b_col_float[4];
	const unsigned char b_col_char[4] = {
	    (unsigned char)(buf_info->col[0] * 255),
	    (unsigned char)(buf_info->col[1] * 255),
	    (unsigned char)(buf_info->col[2] * 255),
	    (unsigned char)(buf_info->col[3] * 255)};

	unsigned char *cbuf;
	int chx, chy;
	int y, x;
	float a, *fbuf;

	BLF_KERNING_VARS(font, has_kerning, kern_mode);

	blf_font_ensure_ascii_table(font);

	/* another buffer specific call for color conversion */
	if (buf_info->display) {
		copy_v4_v4(b_col_float, buf_info->col);
		IMB_colormanagement_display_to_scene_linear_v3(b_col_float, buf_info->display);
	}
	else {
		srgb_to_linearrgb_v4(b_col_float, buf_info->col);
	}

	while (str[i]) {
		BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);

		if (UNLIKELY(c == BLI_UTF8_ERR))
			break;
		if (UNLIKELY(g == NULL))
			continue;
		if (has_kerning)
			BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);

		chx = pen_x + ((int)g->pos_x);
		chy = (int)font->pos[1] + g->height;

		if (g->pitch < 0) {
			pen_y = (int)font->pos[1] + (g->height - (int)g->pos_y);
		}
		else {
			pen_y = (int)font->pos[1] - (g->height - (int)g->pos_y);
		}

		if ((chx + g->width) >= 0 && chx < buf_info->w && (pen_y + g->height) >= 0 && pen_y < buf_info->h) {
			/* don't draw beyond the buffer bounds */
			int width_clip = g->width;
			int height_clip = g->height;
			int yb_start = g->pitch < 0 ? 0 : g->height - 1;

			if (width_clip + chx > buf_info->w)
				width_clip -= chx + width_clip - buf_info->w;
			if (height_clip + pen_y > buf_info->h)
				height_clip -= pen_y + height_clip - buf_info->h;
			
			/* drawing below the image? */
			if (pen_y < 0) {
				yb_start += (g->pitch < 0) ? -pen_y : pen_y;
				height_clip += pen_y;
				pen_y = 0;
			}

			if (buf_info->fbuf) {
				int yb = yb_start;
				for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
					for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
						a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f;

						if (a > 0.0f) {
							float alphatest;
							fbuf = buf_info->fbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w));
							if (a >= 1.0f) {
								fbuf[0] = b_col_float[0];
								fbuf[1] = b_col_float[1];
								fbuf[2] = b_col_float[2];
								fbuf[3] = (alphatest = (fbuf[3] + (b_col_float[3]))) < 1.0f ? alphatest : 1.0f;
							}
							else {
								fbuf[0] = (b_col_float[0] * a) + (fbuf[0] * (1.0f - a));
								fbuf[1] = (b_col_float[1] * a) + (fbuf[1] * (1.0f - a));
								fbuf[2] = (b_col_float[2] * a) + (fbuf[2] * (1.0f - a));
								fbuf[3] = (alphatest = (fbuf[3] + (b_col_float[3] * a))) < 1.0f ? alphatest : 1.0f;
							}
						}
					}

					if (g->pitch < 0)
						yb++;
					else
						yb--;
				}
			}

			if (buf_info->cbuf) {
				int yb = yb_start;
				for (y = 0; y < height_clip; y++) {
					for (x = 0; x < width_clip; x++) {
						a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f;

						if (a > 0.0f) {
							int alphatest;
							cbuf = buf_info->cbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w));
							if (a >= 1.0f) {
								cbuf[0] = b_col_char[0];
								cbuf[1] = b_col_char[1];
								cbuf[2] = b_col_char[2];
								
								alphatest = (int)cbuf[3] + (int)b_col_char[3];
								if (alphatest < 255) {
									cbuf[3] = (unsigned char)(alphatest);
								}
								else {
									cbuf[3] = 255;
								}
							}
							else {
								cbuf[0] = (unsigned char)((b_col_char[0] * a) + (cbuf[0] * (1.0f - a)));
								cbuf[1] = (unsigned char)((b_col_char[1] * a) + (cbuf[1] * (1.0f - a)));
								cbuf[2] = (unsigned char)((b_col_char[2] * a) + (cbuf[2] * (1.0f - a)));
								
								alphatest = ((int)cbuf[3] + (int)((b_col_float[3] * a) * 255.0f));
								if (alphatest < 255) {
									cbuf[3] = (unsigned char)(alphatest);
								}
								else {
									cbuf[3] = 255;
								}
							}
						}
					}

					if (g->pitch < 0)
						yb++;
					else
						yb--;
				}
			}
		}

		pen_x += g->advance_i;
		g_prev = g;
	}
}
Example #4
0
/* float to float pixels, output 4-channel RGBA */
void IMB_buffer_float_from_float(float *rect_to,
                                 const float *rect_from,
                                 int channels_from,
                                 int profile_to,
                                 int profile_from,
                                 bool predivide,
                                 int width,
                                 int height,
                                 int stride_to,
                                 int stride_from)
{
  int x, y;

  /* we need valid profiles */
  BLI_assert(profile_to != IB_PROFILE_NONE);
  BLI_assert(profile_from != IB_PROFILE_NONE);

  if (channels_from == 1) {
    /* single channel input */
    for (y = 0; y < height; y++) {
      const float *from = rect_from + ((size_t)stride_from) * y;
      float *to = rect_to + ((size_t)stride_to) * y * 4;

      for (x = 0; x < width; x++, from++, to += 4) {
        to[0] = to[1] = to[2] = to[3] = from[0];
      }
    }
  }
  else if (channels_from == 3) {
    /* RGB input */
    for (y = 0; y < height; y++) {
      const float *from = rect_from + ((size_t)stride_from) * y * 3;
      float *to = rect_to + ((size_t)stride_to) * y * 4;

      if (profile_to == profile_from) {
        /* no color space conversion */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          copy_v3_v3(to, from);
          to[3] = 1.0f;
        }
      }
      else if (profile_to == IB_PROFILE_LINEAR_RGB) {
        /* convert from sRGB to linear */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          srgb_to_linearrgb_v3_v3(to, from);
          to[3] = 1.0f;
        }
      }
      else if (profile_to == IB_PROFILE_SRGB) {
        /* convert from linear to sRGB */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          linearrgb_to_srgb_v3_v3(to, from);
          to[3] = 1.0f;
        }
      }
    }
  }
  else if (channels_from == 4) {
    /* RGBA input */
    for (y = 0; y < height; y++) {
      const float *from = rect_from + ((size_t)stride_from) * y * 4;
      float *to = rect_to + ((size_t)stride_to) * y * 4;

      if (profile_to == profile_from) {
        /* same profile, copy */
        memcpy(to, from, sizeof(float) * ((size_t)4) * width);
      }
      else if (profile_to == IB_PROFILE_LINEAR_RGB) {
        /* convert to sRGB to linear */
        if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_predivide_v4(to, from);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_v4(to, from);
          }
        }
      }
      else if (profile_to == IB_PROFILE_SRGB) {
        /* convert from linear to sRGB */
        if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            linearrgb_to_srgb_predivide_v4(to, from);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            linearrgb_to_srgb_v4(to, from);
          }
        }
      }
    }
  }
}
Example #5
0
/* float to byte pixels, output 4-channel RGBA */
void IMB_buffer_byte_from_float(uchar *rect_to,
                                const float *rect_from,
                                int channels_from,
                                float dither,
                                int profile_to,
                                int profile_from,
                                bool predivide,
                                int width,
                                int height,
                                int stride_to,
                                int stride_from)
{
  float tmp[4];
  int x, y;
  DitherContext *di = NULL;
  float inv_width = 1.0f / width;
  float inv_height = 1.0f / height;

  /* we need valid profiles */
  BLI_assert(profile_to != IB_PROFILE_NONE);
  BLI_assert(profile_from != IB_PROFILE_NONE);

  if (dither) {
    di = create_dither_context(dither);
  }

  for (y = 0; y < height; y++) {
    float t = y * inv_height;

    if (channels_from == 1) {
      /* single channel input */
      const float *from = rect_from + ((size_t)stride_from) * y;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      for (x = 0; x < width; x++, from++, to += 4) {
        to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
      }
    }
    else if (channels_from == 3) {
      /* RGB input */
      const float *from = rect_from + ((size_t)stride_from) * y * 3;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      if (profile_to == profile_from) {
        /* no color space conversion */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          rgb_float_to_uchar(to, from);
          to[3] = 255;
        }
      }
      else if (profile_to == IB_PROFILE_SRGB) {
        /* convert from linear to sRGB */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          linearrgb_to_srgb_v3_v3(tmp, from);
          rgb_float_to_uchar(to, tmp);
          to[3] = 255;
        }
      }
      else if (profile_to == IB_PROFILE_LINEAR_RGB) {
        /* convert from sRGB to linear */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          srgb_to_linearrgb_v3_v3(tmp, from);
          rgb_float_to_uchar(to, tmp);
          to[3] = 255;
        }
      }
    }
    else if (channels_from == 4) {
      /* RGBA input */
      const float *from = rect_from + ((size_t)stride_from) * y * 4;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      if (profile_to == profile_from) {
        float straight[4];

        /* no color space conversion */
        if (dither && predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t);
          }
        }
        else if (dither) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t);
          }
        }
        else if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            rgba_float_to_uchar(to, straight);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            rgba_float_to_uchar(to, from);
          }
        }
      }
      else if (profile_to == IB_PROFILE_SRGB) {
        /* convert from linear to sRGB */
        unsigned short us[4];
        float straight[4];

        if (dither && predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t);
          }
        }
        else if (dither) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t);
          }
        }
        else if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_v4(to, us);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_v4(to, us);
          }
        }
      }
      else if (profile_to == IB_PROFILE_LINEAR_RGB) {
        /* convert from sRGB to linear */
        if (dither && predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_predivide_v4(tmp, from);
            float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t);
          }
        }
        else if (dither) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_v4(tmp, from);
            float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t);
          }
        }
        else if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_predivide_v4(tmp, from);
            rgba_float_to_uchar(to, tmp);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_v4(tmp, from);
            rgba_float_to_uchar(to, tmp);
          }
        }
      }
    }
  }

  if (dither) {
    clear_dither_context(di);
  }
}
Example #6
0
struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags){
	struct ImBuf *ibuf = NULL;
	png_structp png_ptr;
	png_infop info_ptr;
	unsigned char *pixels = NULL;
	unsigned short *pixels16 = NULL;
	png_bytepp row_pointers = NULL;
	png_uint_32 width, height;
	int bit_depth, color_type;
	PNGReadStruct ps;

	unsigned char *from, *to;
	unsigned short *from16;
	float *to_float;
	float tmp[4];
	int i, bytesperpixel;

	if (imb_is_a_png(mem) == 0) return(NULL);

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
	                                 NULL, NULL, NULL);
	if (png_ptr == NULL) {
		printf("Cannot png_create_read_struct\n");
		return NULL;
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, 
		                        (png_infopp)NULL);
		printf("Cannot png_create_info_struct\n");
		return NULL;
	}

	ps.size = size; /* XXX, 4gig limit! */
	ps.data = mem;
	ps.seek = 0;

	png_set_read_fn(png_ptr, (void *) &ps, ReadData);

	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		if (pixels) MEM_freeN(pixels);
		if (pixels16) MEM_freeN(pixels16);
		if (row_pointers) MEM_freeN(row_pointers);
		if (ibuf) IMB_freeImBuf(ibuf);
		return NULL;
	}

	// png_set_sig_bytes(png_ptr, 8);

	png_read_info(png_ptr, info_ptr);
	png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, 
	             &color_type, NULL, NULL, NULL);

	bytesperpixel = png_get_channels(png_ptr, info_ptr);

	switch (color_type) {
		case PNG_COLOR_TYPE_RGB:
		case PNG_COLOR_TYPE_RGB_ALPHA:
			break;
		case PNG_COLOR_TYPE_PALETTE:
			png_set_palette_to_rgb(png_ptr);
			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
				bytesperpixel = 4;
			}
			else {
				bytesperpixel = 3;
			}
			break;
		case PNG_COLOR_TYPE_GRAY:
		case PNG_COLOR_TYPE_GRAY_ALPHA:
			if (bit_depth < 8) {
				png_set_expand(png_ptr);
				bit_depth = 8;
			}
			break;
		default:
			printf("PNG format not supported\n");
			longjmp(png_jmpbuf(png_ptr), 1);
	}
	
	ibuf = IMB_allocImBuf(width, height, 8 * bytesperpixel, 0);

	if (ibuf) {
		ibuf->ftype = PNG;
		if (bit_depth == 16)
			ibuf->profile = IB_PROFILE_LINEAR_RGB;
		else
			ibuf->profile = IB_PROFILE_SRGB;

		if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
			int unit_type;
			png_uint_32 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");
	}

	if (ibuf && ((flags & IB_test) == 0)) {
		if (bit_depth == 16) {
			imb_addrectfloatImBuf(ibuf);
			png_set_swap(png_ptr);

			pixels16 = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(png_uint_16), "pixels");
			if (pixels16 == NULL) {
				printf("Cannot allocate pixels array\n");
				longjmp(png_jmpbuf(png_ptr), 1);
			}

			// allocate memory for an array of row-pointers
			row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_uint_16p), "row_pointers");
			if (row_pointers == NULL) {
				printf("Cannot allocate row-pointers array\n");
				longjmp(png_jmpbuf(png_ptr), 1);
			}

			// set the individual row-pointers to point at the correct offsets
			for (i = 0; i < ibuf->y; i++) {
				row_pointers[ibuf->y - 1 - i] = (png_bytep)
				                                ((png_uint_16 *)pixels16 + (i * ibuf->x) * bytesperpixel);
			}

			png_read_image(png_ptr, row_pointers);

			// copy image data

			to_float = ibuf->rect_float;
			from16 = pixels16;

			switch (bytesperpixel) {
				case 4:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						tmp[0] = from16[0] / 65535.0;
						tmp[1] = from16[1] / 65535.0;
						tmp[2] = from16[2] / 65535.0;
						tmp[3] = from16[3] / 65535.0;
						srgb_to_linearrgb_v4(to_float, tmp);
						to_float += 4; from16 += 4;
					}
					break;
				case 3:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						tmp[0] = from16[0] / 65535.0;
						tmp[1] = from16[1] / 65535.0;
						tmp[2] = from16[2] / 65535.0;
						tmp[3] = 1.0;
						srgb_to_linearrgb_v4(to_float, tmp);
						to_float += 4; from16 += 3;
					}
					break;
				case 2:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						tmp[0] = tmp[1] = tmp[2] = from16[0] / 65535.0;
						tmp[3] = from16[1] / 65535.0;
						srgb_to_linearrgb_v4(to_float, tmp);
						to_float += 4; from16 += 2;
					}
					break;
				case 1:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						tmp[0] = tmp[1] = tmp[2] = from16[0] / 65535.0;
						tmp[3] = 1.0;
						srgb_to_linearrgb_v4(to_float, tmp);
						to_float += 4; from16++;
					}
					break;
			}
		}
		else {
			imb_addrectImBuf(ibuf);

			pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "pixels");
			if (pixels == NULL) {
				printf("Cannot allocate pixels array\n");
				longjmp(png_jmpbuf(png_ptr), 1);
			}

			// allocate memory for an array of row-pointers
			row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
			if (row_pointers == NULL) {
				printf("Cannot allocate row-pointers array\n");
				longjmp(png_jmpbuf(png_ptr), 1);
			}

			// set the individual row-pointers to point at the correct offsets
			for (i = 0; i < ibuf->y; i++) {
				row_pointers[ibuf->y - 1 - i] = (png_bytep)
				                                ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char));
			}

			png_read_image(png_ptr, row_pointers);

			// copy image data

			to = (unsigned char *) ibuf->rect;
			from = pixels;

			switch (bytesperpixel) {
				case 4:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to[0] = from[0];
						to[1] = from[1];
						to[2] = from[2];
						to[3] = from[3];
						to += 4; from += 4;
					}
					break;
				case 3:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to[0] = from[0];
						to[1] = from[1];
						to[2] = from[2];
						to[3] = 0xff;
						to += 4; from += 3;
					}
					break;
				case 2:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to[0] = to[1] = to[2] = from[0];
						to[3] = from[1];
						to += 4; from += 2;
					}
					break;
				case 1:
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to[0] = to[1] = to[2] = from[0];
						to[3] = 0xff;
						to += 4; from++;
					}
					break;
			}
		}

		if (flags & IB_metadata) {
			png_text *text_chunks;
			int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL);
			for (i = 0; i < count; i++) {
				IMB_metadata_add_field(ibuf, text_chunks[i].key, text_chunks[i].text);
				ibuf->flags |= IB_metadata;
			}
		}

		png_read_end(png_ptr, info_ptr);
	}

	// clean up
	if (pixels)
		MEM_freeN(pixels);
	if (pixels16)
		MEM_freeN(pixels16);
	MEM_freeN(row_pointers);
	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);

	return(ibuf);
}
Example #7
0
void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height,
                       const float col[4], struct ColorManagedDisplay *display,
                       int x1, int y1, int x2, int y2)
{
	int i, j;
	float a; /* alpha */
	float ai; /* alpha inverted */
	float aich; /* alpha, inverted, ai/255.0 - Convert char to float at the same time */
	if ((!rect && !rectf) || (!col) || col[3] == 0.0f)
		return;
	
	/* sanity checks for coords */
	CLAMP(x1, 0, width);
	CLAMP(x2, 0, width);
	CLAMP(y1, 0, height);
	CLAMP(y2, 0, height);

	if (x1 > x2) SWAP(int, x1, x2);
	if (y1 > y2) SWAP(int, y1, y2);
	if (x1 == x2 || y1 == y2) return;
	
	a = col[3];
	ai = 1 - a;
	aich = ai / 255.0f;

	if (rect) {
		unsigned char *pixel; 
		unsigned char chr = 0, chg = 0, chb = 0;
		float fr = 0, fg = 0, fb = 0;

		const int alphaint = FTOCHAR(a);
		
		if (a == 1.0f) {
			chr = FTOCHAR(col[0]);
			chg = FTOCHAR(col[1]);
			chb = FTOCHAR(col[2]);
		}
		else {
			fr = col[0] * a;
			fg = col[1] * a;
			fb = col[2] * a;
		}
		for (j = 0; j < y2 - y1; j++) {
			for (i = 0; i < x2 - x1; i++) {
				pixel = rect + 4 * (((y1 + j) * width) + (x1 + i));
				if (pixel >= rect && pixel < rect + (4 * (width * height))) {
					if (a == 1.0f) {
						pixel[0] = chr;
						pixel[1] = chg;
						pixel[2] = chb;
						pixel[3] = 255;
					}
					else {
						int alphatest;
						pixel[0] = (char)((fr + ((float)pixel[0] * aich)) * 255.0f);
						pixel[1] = (char)((fg + ((float)pixel[1] * aich)) * 255.0f);
						pixel[2] = (char)((fb + ((float)pixel[2] * aich)) * 255.0f);
						pixel[3] = (char)((alphatest = ((int)pixel[3] + alphaint)) < 255 ? alphatest : 255);
					}
				}
			}
		}
	}
	
	if (rectf) {
		float col_conv[4];
		float *pixel;

		if (display) {
			copy_v4_v4(col_conv, col);
			IMB_colormanagement_display_to_scene_linear_v3(col_conv, display);
		}
		else {
			srgb_to_linearrgb_v4(col_conv, col);
		}

		for (j = 0; j < y2 - y1; j++) {
			for (i = 0; i < x2 - x1; i++) {
				pixel = rectf + 4 * (((y1 + j) * width) + (x1 + i));
				if (a == 1.0f) {
					pixel[0] = col_conv[0];
					pixel[1] = col_conv[1];
					pixel[2] = col_conv[2];
					pixel[3] = 1.0f;
				}
				else {
					float alphatest;
					pixel[0] = (col_conv[0] * a) + (pixel[0] * ai);
					pixel[1] = (col_conv[1] * a) + (pixel[1] * ai);
					pixel[2] = (col_conv[2] * a) + (pixel[2] * ai);
					pixel[3] = (alphatest = (pixel[3] + a)) < 1.0f ? alphatest : 1.0f;
				}
			}
		}
	}
}