示例#1
0
pfloat32 * P_APIENTRY pMatrix3x3Interpolate(const pfloat32* matrix1, const pfloat32* matrix2, pfloat32 t, pfloat32* out)
{
#define INTERPOLATE(a, b, t) (a * (1.0f - t) + b * t)

    // Interpolate the scale.
    pfloat32 scale1[2], scale2[2], scale[2];
    pMatrix3x3GetScale(matrix1, scale1[0], scale1[1]);
    pMatrix3x3GetScale(matrix2, scale2[0], scale2[1]);

    scale[0] = INTERPOLATE(scale1[0], scale2[0], t);
    scale[1] = INTERPOLATE(scale1[1], scale2[1], t);

    pfloat32 theta1 = atan2f(matrix1[4], matrix1[1]);
    pfloat32 theta2 = atan2f(matrix2[4], matrix2[1]);
    pfloat32 theta = INTERPOLATE(theta1, theta2, t);

    pMatrix3x3CreateRotation(theta, out);

    out[0] *= scale[0];
    out[1] *= scale[1];
    
    out[3] *= scale[0];
    out[4] *= scale[1];
    
    out[6] = INTERPOLATE(matrix1[6], matrix2[6], t);
    out[7] = INTERPOLATE(matrix1[7], matrix2[7], t);

#undef INTERPOLATE

    return out;
}
示例#2
0
void CCrossDlg::UpdateMix(double Pos)
{
	for (int i = 0; i < ROWS; i++) {
		m_Info[SEL_MIX].m_Row[i].Val	= INTERPOLATE(Val);
		m_Info[SEL_MIX].m_Row[i].Wave =	// don't interpolate waveform, threshold it
			Pos < .5 ? m_Info[SEL_A].m_Row[i].Wave : m_Info[SEL_B].m_Row[i].Wave;
		m_Info[SEL_MIX].m_Row[i].Amp	= INTERPOLATE(Amp);
		m_Info[SEL_MIX].m_Row[i].Freq	= INTERPOLATE(Freq);
		m_Info[SEL_MIX].m_Row[i].PW		= INTERPOLATE(PW);
	}
	m_Frm->OnNewParms(SEL_MIX);	// update parameters dialog
}
示例#3
0
  void Arpeggiator::process() {
    mopo_float frequency = input(kFrequency)->at(0);
    float min_gate = (MIN_VOICE_TIME + VOICE_KILL_TIME) * frequency;
    mopo_float gate = INTERPOLATE(min_gate, 1.0, input(kGate)->at(0));

    mopo_float delta_phase = frequency / sample_rate_;
    mopo_float new_phase = phase_ + buffer_size_ * delta_phase;

    // If we're past the gate phase and we're playing a note, turn it off.
    if (new_phase >= gate && last_played_note_ >= 0) {
      int offset = CLAMP((gate - phase_) / delta_phase, 0, buffer_size_ - 1);
      note_handler_->noteOff(last_played_note_, offset);
      last_played_note_ = -1;
    }

    // Check if it's time to play the next note.
    if (getNumNotes() && new_phase >= 1) {
      int offset = CLAMP((1 - phase_) / delta_phase, 0, buffer_size_ - 1);
      std::pair<mopo_float, mopo_float> note = getNextNote();
      note_handler_->noteOn(note.first, note.second, offset);
      last_played_note_ = note.first;
      phase_ = new_phase - 1.0;
    }
    else
      phase_ = new_phase;
  }
示例#4
0
文件: envelope.cpp 项目: eriser/mopo
 inline mopo_float Envelope::tick(int i) {
   if (state_ == kAttacking) {
     if (inputs_[kAttack]->at(i) <= 0)
       current_value_ = 1;
     else {
       mopo_float change = 1.0 / (sample_rate_ * inputs_[kAttack]->at(i));
       current_value_ = CLAMP(current_value_ + change, 0, 1);
     }
     if (current_value_ >= 1)
       state_ = kDecaying;
   }
   else if (state_ == kDecaying) {
     current_value_ = INTERPOLATE(inputs_[kSustain]->at(i), current_value_,
                                  decay_decay_);
   }
   else if (state_ == kKilling) {
     current_value_ -= CLAMP(1 / (KILL_TIME * sample_rate_), 0, 1);
     if (current_value_ <= 0) {
       outputs_[kFinished]->trigger(kVoiceReset, i);
       state_ = kAttacking;
     }
   }
   else if (state_ == kReleasing)
     current_value_ *= release_decay_;
   return current_value_;
 }
示例#5
0
void draw_preview(unsigned short *dest, int x, int y) {
	uint8 *PBuf = g_preview;
	uint16 *dst = (uint16 *) dest;

	PBuf += 256 * 8;
	dst += y * 320 + x;

	for (y = 0; y < 76; y++) {
		for (x = 0; x < 32; x++) {
			*dst++ = INTERPOLATE(g_psdl[*PBuf], g_psdl[*(PBuf+1)]);
			*dst++ = INTERPOLATE(g_psdl[*(PBuf+3)], g_psdl[*(PBuf+4)]);
			*dst++ = INTERPOLATE(g_psdl[*(PBuf+7)], g_psdl[*(PBuf+6)]);
			PBuf += 8;
		}

		PBuf += 256 * 2;
		dst += 224;
	}
}
示例#6
0
pfloat32 * P_APIENTRY pMatrix4x4Interpolate(const pfloat32 *matrix1, const pfloat32 *matrix2, pfloat32 t, pfloat32 *out)
{
#define INTERPOLATE(a, b, t) (a * (1.0f - t) + b * t)
    // Interpolate the rotation.
    pfloat32 q1[4], q2[4], q[4];
    pQuaternionFromMatrix4x4(matrix1, q1);
    pQuaternionFromMatrix4x4(matrix2, q2);
    pQuaternionSlerp(q1, q2, t, q);
    pQuaternionGetMatrix4x4(q, out);

    // Interpolate the scale.
    pfloat32 scale1[3], scale2[3], scale[3];
    pMatrix4x4GetScaling(matrix1, &scale1[0], &scale1[1], &scale1[2]);
    pMatrix4x4GetScaling(matrix2, &scale2[0], &scale2[1], &scale2[2]);

    scale[0] = INTERPOLATE(scale1[0], scale2[0], t);
    scale[1] = INTERPOLATE(scale1[1], scale2[1], t);
    scale[2] = INTERPOLATE(scale1[2], scale2[2], t);

    pMatrix4x4Scale(out, scale[0], scale[1], scale[2]);

    // Interpolate the translation.
    out[12] = INTERPOLATE(matrix1[12], matrix2[12], t);
    out[13] = INTERPOLATE(matrix1[13], matrix2[13], t);
    out[14] = INTERPOLATE(matrix1[14], matrix2[14], t);

#undef INTERPOLATE

    return out;
}
示例#7
0
static gboolean
clutter_rect_progress (const GValue *a,
                       const GValue *b,
                       gdouble       progress,
                       GValue       *retval)
{
  const ClutterRect *rect_a = g_value_get_boxed (a);
  const ClutterRect *rect_b = g_value_get_boxed (b);
  ClutterRect res = CLUTTER_RECT_INIT_ZERO;

#define INTERPOLATE(r_a,r_b,member,field,factor)     ((r_a)->member.field + (((r_b)->member.field - ((r_a)->member.field)) * (factor)))

  res.origin.x = INTERPOLATE (rect_a, rect_b, origin, x, progress);
  res.origin.y = INTERPOLATE (rect_a, rect_b, origin, y, progress);

  res.size.width = INTERPOLATE (rect_a, rect_b, size, width, progress);
  res.size.height = INTERPOLATE (rect_a, rect_b, size, height, progress);

#undef INTERPOLATE

  g_value_set_boxed (retval, &res);

  return TRUE;
}
static int get_battery_temperature(int resistance)
{
	struct power_supply *ps = power_supply_get_by_name(SEMC_BDATA_NAME);
	struct data_info *di = container_of(ps, struct data_info, bdata_ps);
	int i;
	int temp;
	enum battery_technology type;
	int num_table_elements;
	const struct resistance_vs_temperature_semc *table_p;

	type = get_battery_type(resistance);

	if (type == BATTERY_TECHNOLOGY_TYPE1) {
		table_p = &fallback_resistance_vs_temperature_type1[0];
		num_table_elements =
			sizeof(fallback_resistance_vs_temperature_type1) /
			sizeof(struct resistance_vs_temperature_semc);
	} else if (type == BATTERY_TECHNOLOGY_TYPE2) {
		table_p = &fallback_resistance_vs_temperature_type2[0];
		num_table_elements =
			sizeof(fallback_resistance_vs_temperature_type2) /
			sizeof(struct resistance_vs_temperature_semc);
	} else {
		temp = DEFAULT_TEMPERATURE_UNKNOWN_BATT_TYPE;
		return temp;
	}

	for (i = 0; i < num_table_elements; i++) {
		if (resistance < table_p[i].resistance)
			break;
	}

	if ((i > 0) && (i < num_table_elements)) {
		temp = INTERPOLATE(resistance,
					table_p[i].resistance,
					table_p[i].temperature,
					table_p[i-1].resistance,
					table_p[i-1].temperature);
	} else if (i == 0) {
		temp = table_p[0].temperature;
	} else {
		temp = table_p[num_table_elements - 1].temperature;
	}
	dev_dbg(di->dev, "%s() resist=%d type=%d temp=%d\n",
		__func__, resistance, type, temp);
	return temp;
}
示例#9
0
void FilterResponse::computeFilterCoefficients() {
  if (cutoff_slider_ == nullptr || resonance_slider_ == nullptr || filter_type_slider_ == nullptr)
    return;

  mopo::Filter::Type type = static_cast<mopo::Filter::Type>(
                            static_cast<int>(filter_type_slider_->getValue()));
  double frequency = mopo::utils::midiNoteToFrequency(cutoff_slider_->getValue());
  double resonance = mopo::utils::magnitudeToQ(resonance_slider_->getValue());
  double decibals = INTERPOLATE(MIN_GAIN_DB, MAX_GAIN_DB, resonance_slider_->getValue());
  double gain = mopo::utils::dbToGain(decibals);
  if (type == mopo::Filter::kLowShelf ||
      type == mopo::Filter::kHighShelf ||
      type == mopo::Filter::kBandShelf) {
    filter_.computeCoefficients(type, frequency, 1.0, gain);
  }
  else {
    filter_.computeCoefficients(type, frequency, resonance, 1.0);
  }
  resetResponsePath();
}
示例#10
0
void WaveViewer::drawSmoothRandom() {
  float amplitude = amplitude_slider_ ? amplitude_slider_->getValue() : 1.0f;
  float draw_width = getWidth();
  float draw_height = getHeight() - 2.0f * PADDING;

  float start_val = amplitude * random_values[0];
  wave_path_.startNewSubPath(-50, getHeight() / 2.0f);
  wave_path_.lineTo(0, PADDING + draw_height * ((1.0f - start_val) / 2.0f));
  for (int i = 1; i < resolution_ - 1; ++i) {
    float t = (1.0f * i) / resolution_;
    float phase = t * (NOISE_RESOLUTION - 1);
    int index = (int)phase;
    phase = mopo::PI * (phase - index);
    float val = amplitude * INTERPOLATE(random_values[index],
                                        random_values[index + 1],
                                        0.5 - cos(phase) / 2.0);
    wave_path_.lineTo(t * draw_width, PADDING + draw_height * ((1.0f - val) / 2.0f));
  }

  float end_val = amplitude * random_values[NOISE_RESOLUTION - 1];
  wave_path_.lineTo(getWidth(), PADDING + draw_height * ((1.0f - end_val) / 2.0f));
  wave_path_.lineTo(getWidth() + 50, getHeight() / 2.0f);

}
示例#11
0
bool C4LandscapeRenderGL::LoadScaler(C4GroupSet *pGroups)
{
	// Search for scaler
	C4Group *pGroup = pGroups->FindEntry(C4CFN_LandscapeScaler);
	if(!pGroup) return false;
	// Load scaler from group
	if(!fctScaler.Load(*pGroup, C4CFN_LandscapeScaler, C4FCT_Full, C4FCT_Full, false, 0))
		return false;
	// Check size
	const int iOrigWdt = 8 * 3, iOrigHgt = 4 * 8 * 3;
	const int iFactor = fctScaler.Wdt / iOrigWdt;
	if(fctScaler.Wdt != iFactor * iOrigWdt || fctScaler.Hgt != iFactor * iOrigHgt)
	{
		LogF("  gl: Unexpected scaler size - should be multiple of %dx%d!", iOrigWdt, iOrigHgt);
		return false;
	}
	// Walk through all lookups we have in the texture and decide where
	// to look for the "other" pixel. This might not be unique later on,
	// so it is a good idea to have a proper priority order here.
	fctScaler.Surface->Lock();
	int i;
	for (i = 0; i < 8 * 4 * 8; i++) {
		// Decode from ID what pixels are expected to be set in this case
		enum Px      { NW,  N, NE,  W,  E, SW, S, SE, X };
		int p_x[9] = { -1,  0,  1, -1,  1, -1, 0, 1,  0 };
		int p_y[9] = { -1, -1, -1,  0,  0,  1, 1, 1,  0 };
		bool pxAt[X];
		for(int j = 0; j < X; j++)
			pxAt[j] = !!(i & (1 << j));
		// Oc = octant borders. Set up arrays to get righthand border
		// of an octant, in a way that we can easily rotate further.
		enum Oc { NWW, NEE, SWW, SEE, NNW, NNE, SSW, SSE };
		int p2a[8] = { 5, 6, 7, 4, 0, 3, 2, 1 };
		Oc a2o[8] = { SEE, SSE, SSW, SWW, NWW, NNW, NNE, NEE };
		// Decide in which octant we want to interpolate towards
		// which pixel. Pick the nearest unset pixel using a special
		// priority order.
		Px opx[8] = { X,X,X,X,X,X,X,X };
		#define INTERPOLATE(x,da) do { \
			int y = a2o[(8+p2a[x]+(da)) % 8];\
			if (!pxAt[x] && opx[y] == X) opx[y] = x; \
		} while(false)
		for(int j = 0; j < 4; j++) {
			// vertical
			INTERPOLATE(N, j); INTERPOLATE(N, -j-1);
			INTERPOLATE(S, j); INTERPOLATE(S, -j-1);
			// horizontal
			INTERPOLATE(W, j); INTERPOLATE(W, -j-1);
			INTERPOLATE(E, j); INTERPOLATE(E, -j-1);
			// diagonals
			INTERPOLATE(NW, j); INTERPOLATE(NW, -j-1);
			INTERPOLATE(SW, j); INTERPOLATE(SW, -j-1);
			INTERPOLATE(NE, j); INTERPOLATE(NE, -j-1);
			INTERPOLATE(SE, j); INTERPOLATE(SE, -j-1);			
		}
		// Decide in which octants we will not interpolate normals.
		// It doesn't make sense when there's another material in that
		// general direction, as then the bias of that will factor into
		// the interpolation, giving bright borders on dark shading,
		// and vice-versa.
		bool noNormals[8];
		noNormals[NNW] = noNormals[NWW] = !pxAt[W] || !pxAt[NW] || !pxAt[N];
		noNormals[NNE] = noNormals[NEE] = !pxAt[E] || !pxAt[NE] || !pxAt[N];
		noNormals[SSW] = noNormals[SWW] = !pxAt[W] || !pxAt[SW] || !pxAt[S];
		noNormals[SSE] = noNormals[SEE] = !pxAt[E] || !pxAt[SE] || !pxAt[S];
		// Set blue and green components to relative coordinates of
		// "other" pixel, and alpha to mix param for normals
		const int x0 = (i % 8) * 3 * iFactor;
		const int y0 = (i / 8) * 3 * iFactor;
		const int iPxs = 3 * iFactor;
		int y, x;

		for(y = 0; y < iPxs; y++)
		{
			for(x = 0; x < iPxs; x++)
			{
				// Find out in which octagon we are
				int oct = 0;
				if(2 * x >= iPxs) oct+=1;
				if(2 * y >= iPxs) oct+=2;
				if((x >= y) != (x >= iPxs - y)) oct+=4;
				// Get pixel, do processing
				DWORD pix = fctScaler.Surface->GetPixDw(x0+x, y0+y, false);
				BYTE val = GetGreenValue(pix);
				if(val >= 250) val = 255;
				BYTE bx = 64 * (p_x[opx[oct]] + 1);
				BYTE by = 64 * (p_y[opx[oct]] + 1);
				BYTE bn = (noNormals[oct] ? 255 : 1);
				fctScaler.Surface->SetPixDw(x0+x, y0+y, RGBA(val, bx, by, bn));
			}
		}
	}
	return fctScaler.Surface->Unlock();
}
示例#12
0
void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, ALLEGRO_BITMAP *dest, uint32 width, uint32 height) {

	int j, v;
	unsigned int x, y;
	int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest));
	unsigned long color[12];
	unsigned char **src_line = new unsigned char*[4];
	unsigned char **dst_line = new unsigned char*[2];

	/* Point to the first 3 lines. */
	src_line[0] = src;
	src_line[1] = src;
	src_line[2] = src + src_pitch;
	src_line[3] = src + src_pitch * 2;
	
	/* Can we write the results directly? */
	if (is_video_bitmap(dest) || is_planar_bitmap(dest)) {
		//dst_line[0] = malloc(sizeof(char) * sbpp * width);
		//dst_line[1] = malloc(sizeof(char) * sbpp * width);
		dst_line[0] = new unsigned char[sbpp*width];
		dst_line[1] = new unsigned char[sbpp*width];
		v = 1;
	}
	else {
		dst_line[0] = dest->line[0];
		dst_line[1] = dest->line[1];
		v = 0;
	}
	
	/* Set destination */
	bmp_select(dest);

	x = 0, y = 0;
	
	if (PixelsPerMask == 2) {
		unsigned short *sbp;
		sbp = (unsigned short*)src_line[0];
		color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = *(sbp + 1); color[5] = *(sbp + 2);
		sbp = (unsigned short*)src_line[2];
		color[6] = *sbp;     color[7] = color[6];     color[8] = *(sbp + 1); color[9] = *(sbp + 2);
		sbp = (unsigned short*)src_line[3];
		color[10] = *sbp;    color[11] = *(sbp + 1); 
	}
	else {
		unsigned long *lbp;
		lbp = (unsigned long*)src_line[0];
		color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = *(lbp + 1); color[5] = *(lbp + 2);
		lbp = (unsigned long*)src_line[2];
		color[6] = *lbp;     color[7] = color[6];     color[8] = *(lbp + 1); color[9] = *(lbp + 2);
		lbp = (unsigned long*)src_line[3];
		color[10] = *lbp;    color[11] = *(lbp + 1);
	}

	for (y = 0; y < height; y++) {
	
		/* Todo: x = width - 2, x = width - 1 */
		
		for (x = 0; x < width; x++) {
			unsigned long product1a, product1b, product2a, product2b;

//---------------------------------------     B1 B2           0  1
//                                         4  5  6  S2 ->  2  3  4  5
//                                         1  2  3  S1     6  7  8  9
//                                            A1 A2          10 11

			if (color[7] == color[4] && color[3] != color[8]) {
				product1b = product2a = color[7];

				if ((color[6] == color[7]) || (color[4] == color[1]))
					product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3]));
				else
					product1a = INTERPOLATE(color[3], color[4]);

				if ((color[4] == color[5]) || (color[7] == color[10]))
					product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8]));
				else
					product2b = INTERPOLATE(color[7], color[8]);
			}
			else if (color[3] == color[8] && color[7] != color[4]) {
				product2b = product1a = color[3];

				if ((color[0] == color[3]) || (color[5] == color[9]))
					product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4]));
				else
					product1b = INTERPOLATE(color[3], color[1]);

				if ((color[8] == color[11]) || (color[2] == color[3]))
					product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2]));
				else
					product2a = INTERPOLATE(color[7], color[8]);

			}
			else if (color[3] == color[8] && color[7] == color[4]) {
				register int r = 0;

				r += GET_RESULT(color[4], color[3], color[6], color[10]);
				r += GET_RESULT(color[4], color[3], color[2], color[0]);
				r += GET_RESULT(color[4], color[3], color[11], color[9]);
				r += GET_RESULT(color[4], color[3], color[1], color[5]);

				if (r > 0) {
					product1b = product2a = color[7];
					product1a = product2b = INTERPOLATE(color[3], color[4]);
				}
				else if (r < 0) {
					product2b = product1a = color[3];
					product1b = product2a = INTERPOLATE(color[3], color[4]);
				}
				else {
					product2b = product1a = color[3];
					product1b = product2a = color[7];
				}
			}
			else {
				product2b = product1a = INTERPOLATE(color[7], color[4]);
				product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b);
				product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a);

				product2a = product1b = INTERPOLATE(color[3], color[8]);
				product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a);
				product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b);
			}

			if (PixelsPerMask == 2) {
				*((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
				*((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
			}
			else {
				*((unsigned long *) (&dst_line[0][x * 8])) = product1a;
				*((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
				*((unsigned long *) (&dst_line[1][x * 8])) = product2a;
				*((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
			}
			
			/* Move color matrix forward */
			color[0] = color[1]; 
			color[2] = color[3]; color[3] = color[4]; color[4] = color[5];
			color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; 
			color[10] = color[11];
			
			if (x < width - 2) {
				x += 2;
				if (PixelsPerMask == 2) {
					color[1] = *(((unsigned short*)src_line[0]) + x);
					if (x < width) {
						color[5] = *(((unsigned short*)src_line[1]) + x + 1);
						color[9] = *(((unsigned short*)src_line[2]) + x + 1);
					}
					color[11] = *(((unsigned short*)src_line[3]) + x);
				}
				else {
					color[1] = *(((unsigned long*)src_line[0]) + x);
					if (x < width) {
						color[5] = *(((unsigned long*)src_line[1]) + x + 1);
						color[9] = *(((unsigned long*)src_line[2]) + x + 1);
					}
					color[11] = *(((unsigned long*)src_line[3]) + x);
				}
				x -= 2;
			}
		}

		/* We're done with one line, so we shift the source lines up */
		src_line[0] = src_line[1];
		src_line[1] = src_line[2];
		src_line[2] = src_line[3];		

		/* Read next line */
		if (y + 3 >= height)
			src_line[3] = src_line[2];
		else
			src_line[3] = src_line[2] + src_pitch;
			
		/* Then shift the color matrix up */
		if (PixelsPerMask == 2) {
			unsigned short *sbp;
			sbp = (unsigned short*)src_line[0];
			color[0] = *sbp;     color[1] = *(sbp + 1);
			sbp = (unsigned short*)src_line[1];
			color[2] = *sbp;     color[3] = color[2];    color[4] = *(sbp + 1);  color[5] = *(sbp + 2);
			sbp = (unsigned short*)src_line[2];
			color[6] = *sbp;     color[7] = color[6];    color[8] = *(sbp + 1);  color[9] = *(sbp + 2);
			sbp = (unsigned short*)src_line[3];
			color[10] = *sbp;    color[11] = *(sbp + 1);
		}
		else {
			unsigned long *lbp;
			lbp = (unsigned long*)src_line[0];
			color[0] = *lbp;     color[1] = *(lbp + 1);
			lbp = (unsigned long*)src_line[1];
			color[2] = *lbp;     color[3] = color[2];    color[4] = *(lbp + 1);  color[5] = *(lbp + 2);
			lbp = (unsigned long*)src_line[2];
			color[6] = *lbp;     color[7] = color[6];    color[8] = *(lbp + 1);  color[9] = *(lbp + 2);
			lbp = (unsigned long*)src_line[3];
			color[10] = *lbp;    color[11] = *(lbp + 1);
		}


		/* Write the 2 lines, if not already done so */
		if (v) {
			unsigned long dst_addr;
		
			dst_addr = bmp_write_line(dest, y * 2);
			for (j = 0; j < dest->w * sbpp; j += sizeof(long))
				bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j)));
				
			dst_addr = bmp_write_line(dest, y * 2 + 1);
			for (j = 0; j < dest->w * sbpp; j += sizeof(long))
				bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j)));
		}
		else {
			if (y < height - 1) {
				dst_line[0] = dest->line[y * 2 + 2];
				dst_line[1] = dest->line[y * 2 + 3];
			}
		}
	}
	bmp_unwrite_line(dest);
	
	if (v) {
		delete dst_line[0];
		delete dst_line[1];
	}
	delete[] src_line;
	delete[] dst_line;

}
static void super2xsai(AVFilterContext *ctx,
                       uint8_t *src, int src_linesize,
                       uint8_t *dst, int dst_linesize,
                       int width, int height)
{
    Super2xSaIContext *sai = ctx->priv;
    unsigned int x, y;
    uint32_t color[4][4];
    unsigned char *src_line[4];
    const int bpp = sai->bpp;
    const uint32_t hi_pixel_mask = sai->hi_pixel_mask;
    const uint32_t lo_pixel_mask = sai->lo_pixel_mask;
    const uint32_t q_hi_pixel_mask = sai->q_hi_pixel_mask;
    const uint32_t q_lo_pixel_mask = sai->q_lo_pixel_mask;

    /* Point to the first 4 lines, first line is duplicated */
    src_line[0] = src;
    src_line[1] = src;
    src_line[2] = src + src_linesize*FFMIN(1, height-1);
    src_line[3] = src + src_linesize*FFMIN(2, height-1);

#define READ_COLOR4(dst, src_line, off) dst = *((const uint32_t *)src_line + off)
#define READ_COLOR3(dst, src_line, off) dst = AV_RL24 (src_line + 3*off)
#define READ_COLOR2(dst, src_line, off) dst = sai->is_be ? AV_RB16(src_line + 2 * off) : AV_RL16(src_line + 2 * off)

    for (y = 0; y < height; y++) {
        uint8_t *dst_line[2];

        dst_line[0] = dst + dst_linesize*2*y;
        dst_line[1] = dst + dst_linesize*(2*y+1);

        switch (bpp) {
        case 4:
            READ_COLOR4(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR4(color[0][2], src_line[0], 1); READ_COLOR4(color[0][3], src_line[0], 2);
            READ_COLOR4(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR4(color[1][2], src_line[1], 1); READ_COLOR4(color[1][3], src_line[1], 2);
            READ_COLOR4(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR4(color[2][2], src_line[2], 1); READ_COLOR4(color[2][3], src_line[2], 2);
            READ_COLOR4(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR4(color[3][2], src_line[3], 1); READ_COLOR4(color[3][3], src_line[3], 2);
            break;
        case 3:
            READ_COLOR3(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR3(color[0][2], src_line[0], 1); READ_COLOR3(color[0][3], src_line[0], 2);
            READ_COLOR3(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR3(color[1][2], src_line[1], 1); READ_COLOR3(color[1][3], src_line[1], 2);
            READ_COLOR3(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR3(color[2][2], src_line[2], 1); READ_COLOR3(color[2][3], src_line[2], 2);
            READ_COLOR3(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR3(color[3][2], src_line[3], 1); READ_COLOR3(color[3][3], src_line[3], 2);
            break;
        default:
            READ_COLOR2(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR2(color[0][2], src_line[0], 1); READ_COLOR2(color[0][3], src_line[0], 2);
            READ_COLOR2(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR2(color[1][2], src_line[1], 1); READ_COLOR2(color[1][3], src_line[1], 2);
            READ_COLOR2(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR2(color[2][2], src_line[2], 1); READ_COLOR2(color[2][3], src_line[2], 2);
            READ_COLOR2(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR2(color[3][2], src_line[3], 1); READ_COLOR2(color[3][3], src_line[3], 2);
        }

        for (x = 0; x < width; x++) {
            uint32_t product1a, product1b, product2a, product2b;

//---------------------------------------  B0 B1 B2 B3    0  1  2  3
//                                         4  5* 6  S2 -> 4  5* 6  7
//                                         1  2  3  S1    8  9 10 11
//                                         A0 A1 A2 A3   12 13 14 15
//--------------------------------------
            if (color[2][1] == color[1][2] && color[1][1] != color[2][2]) {
                product2b = color[2][1];
                product1b = product2b;
            } else if (color[1][1] == color[2][2] && color[2][1] != color[1][2]) {
                product2b = color[1][1];
                product1b = product2b;
            } else if (color[1][1] == color[2][2] && color[2][1] == color[1][2]) {
                int r = 0;

                r += GET_RESULT(color[1][2], color[1][1], color[1][0], color[3][1]);
                r += GET_RESULT(color[1][2], color[1][1], color[2][0], color[0][1]);
                r += GET_RESULT(color[1][2], color[1][1], color[3][2], color[2][3]);
                r += GET_RESULT(color[1][2], color[1][1], color[0][2], color[1][3]);

                if (r > 0)
                    product1b = color[1][2];
                else if (r < 0)
                    product1b = color[1][1];
                else
                    product1b = INTERPOLATE(color[1][1], color[1][2]);

                product2b = product1b;
            } else {
                if (color[1][2] == color[2][2] && color[2][2] == color[3][1] && color[2][1] != color[3][2] && color[2][2] != color[3][0])
                    product2b = Q_INTERPOLATE(color[2][2], color[2][2], color[2][2], color[2][1]);
                else if (color[1][1] == color[2][1] && color[2][1] == color[3][2] && color[3][1] != color[2][2] && color[2][1] != color[3][3])
                    product2b = Q_INTERPOLATE(color[2][1], color[2][1], color[2][1], color[2][2]);
                else
                    product2b = INTERPOLATE(color[2][1], color[2][2]);

                if (color[1][2] == color[2][2] && color[1][2] == color[0][1] && color[1][1] != color[0][2] && color[1][2] != color[0][0])
                    product1b = Q_INTERPOLATE(color[1][2], color[1][2], color[1][2], color[1][1]);
                else if (color[1][1] == color[2][1] && color[1][1] == color[0][2] && color[0][1] != color[1][2] && color[1][1] != color[0][3])
                    product1b = Q_INTERPOLATE(color[1][2], color[1][1], color[1][1], color[1][1]);
                else
                    product1b = INTERPOLATE(color[1][1], color[1][2]);
            }

            if (color[1][1] == color[2][2] && color[2][1] != color[1][2] && color[1][0] == color[1][1] && color[1][1] != color[3][2])
                product2a = INTERPOLATE(color[2][1], color[1][1]);
            else if (color[1][1] == color[2][0] && color[1][2] == color[1][1] && color[1][0] != color[2][1] && color[1][1] != color[3][0])
                product2a = INTERPOLATE(color[2][1], color[1][1]);
            else
                product2a = color[2][1];

            if (color[2][1] == color[1][2] && color[1][1] != color[2][2] && color[2][0] == color[2][1] && color[2][1] != color[0][2])
                product1a = INTERPOLATE(color[2][1], color[1][1]);
            else if (color[1][0] == color[2][1] && color[2][2] == color[2][1] && color[2][0] != color[1][1] && color[2][1] != color[0][0])
                product1a = INTERPOLATE(color[2][1], color[1][1]);
            else
                product1a = color[1][1];

            /* Set the calculated pixels */
            switch (bpp) {
            case 4:
                AV_WN32A(dst_line[0] + x * 8,     product1a);
                AV_WN32A(dst_line[0] + x * 8 + 4, product1b);
                AV_WN32A(dst_line[1] + x * 8,     product2a);
                AV_WN32A(dst_line[1] + x * 8 + 4, product2b);
                break;
            case 3:
                AV_WL24(dst_line[0] + x * 6,     product1a);
                AV_WL24(dst_line[0] + x * 6 + 3, product1b);
                AV_WL24(dst_line[1] + x * 6,     product2a);
                AV_WL24(dst_line[1] + x * 6 + 3, product2b);
                break;
            default: // bpp = 2
                if (sai->is_be) {
                    AV_WB32(dst_line[0] + x * 4, product1a | (product1b << 16));
                    AV_WB32(dst_line[1] + x * 4, product2a | (product2b << 16));
                } else {
                    AV_WL32(dst_line[0] + x * 4, product1a | (product1b << 16));
                    AV_WL32(dst_line[1] + x * 4, product2a | (product2b << 16));
                }
            }

            /* Move color matrix forward */
            color[0][0] = color[0][1]; color[0][1] = color[0][2]; color[0][2] = color[0][3];
            color[1][0] = color[1][1]; color[1][1] = color[1][2]; color[1][2] = color[1][3];
            color[2][0] = color[2][1]; color[2][1] = color[2][2]; color[2][2] = color[2][3];
            color[3][0] = color[3][1]; color[3][1] = color[3][2]; color[3][2] = color[3][3];

            if (x < width - 3) {
                x += 3;
                switch (bpp) {
                case 4:
                    READ_COLOR4(color[0][3], src_line[0], x);
                    READ_COLOR4(color[1][3], src_line[1], x);
                    READ_COLOR4(color[2][3], src_line[2], x);
                    READ_COLOR4(color[3][3], src_line[3], x);
                    break;
                case 3:
                    READ_COLOR3(color[0][3], src_line[0], x);
                    READ_COLOR3(color[1][3], src_line[1], x);
                    READ_COLOR3(color[2][3], src_line[2], x);
                    READ_COLOR3(color[3][3], src_line[3], x);
                    break;
                default:        /* case 2 */
                    READ_COLOR2(color[0][3], src_line[0], x);
                    READ_COLOR2(color[1][3], src_line[1], x);
                    READ_COLOR2(color[2][3], src_line[2], x);
                    READ_COLOR2(color[3][3], src_line[3], x);
                }
                x -= 3;
            }
        }

        /* We're done with one line, so we shift the source lines up */
        src_line[0] = src_line[1];
        src_line[1] = src_line[2];
        src_line[2] = src_line[3];

        /* Read next line */
        src_line[3] = src_line[2];
        if (y < height - 3)
            src_line[3] += src_linesize;
    } // y loop
}
示例#14
0
Pixmap MwAnimatorPixmap(Widget w, int ani_now)
{
	MwAnimatorWidget aw = (MwAnimatorWidget)w;
	GC ani_gc = aw->animator.gc;
	Display *display = XtDisplay(w);
	Window ani_win = XtWindow(w);
	MwFmt fmt;
	XColor color;

	int x, y, x1, y1, x2, y2;
	unsigned int b1, d1;
	Window root;
	int width, height;
	unsigned int w1, h1;
	int visible;
	int angle1, angle2;
	MwAniObject *actor;
	ani_image *img, *bg_image;
	Pixmap scribble;
	unsigned int ani_width, ani_height, ani_depth;
	MwRichchar *p;
	char *bg_pixmap = aw->animator.bg_pixmap;

	if (!XtIsRealized(w)) return None;

	ani_width = aw->core.width;
	ani_height = aw->core.height;
	ani_depth = aw->core.depth;
	if (ani_width > 2000 || ani_height > 2000) return None;

	scribble = XCreatePixmap(display, ani_win,
		ani_width, ani_height, ani_depth);

	draw_gradient(w, scribble);

	/* tile the background */
	bg_image = name2image(w, bg_pixmap);

	if (bg_image) {
		int bg_x, bg_y;
		unsigned int bg_width, bg_height, bg_border, bg_depth;

		XSetClipMask(display, ani_gc, bg_image->mask);

		XGetGeometry(display, bg_image->pixmap, &root, &bg_x, &bg_y,
				&bg_width, &bg_height, &bg_border, &bg_depth);
		for (y = 0; y < ani_height; y += bg_height) {
			for (x = 0; x < ani_width; x += bg_width) {
				XSetClipOrigin(display, ani_gc, x, y);
				XCopyArea(display, bg_image->pixmap, scribble,
					ani_gc, 0, 0,
					bg_width, bg_height, x, y);
			}
		}
	}

	/* now loop over the objects, drawing each in the right place */
	for (actor = aw->animator.cast; actor; actor = actor->next) {
		/* find the tick before and after ani_now and
		   interpolate to find position and size.
		   the script always contains a tick for time=0 */
		MwAniScript *before, *after;

		before = actor->script;		/* this is never NULL */
		while (before->next) {
			if (before->next->time > ani_now) break;
			before = before->next;
		}
		after = before->next;
		visible = before->visible;
		if (!visible) continue;

		/* set color */
		MwDecodeFormat(actor->fmt, MW_FMT_FG, &fmt);
		/* fmt.fg is now the color name */
		MwAllocNamedColor(display, fmt.fg, &color);
		XSetForeground(display, ani_gc, color.pixel);

		XSetClipMask(display, ani_gc, None);

		if (!after) {	/* object remains at before */
			x = before->x;
			y = before->y;
			width = before->width;
			height = before->height;
		} else {	/* interpolate */
			x = INTERPOLATE(before->x, after->x,
				ani_now, before->time, after->time);
			y = INTERPOLATE(before->y, after->y,
				ani_now, before->time, after->time);
			width = INTERPOLATE(before->width, after->width,
				ani_now, before->time, after->time);
			height = INTERPOLATE(before->height, after->height,
				ani_now, before->time, after->time);
		}

		switch (actor->type) {
		case MW_ANI_NONE:
			break;
		case MW_ANI_LINE:
			x2 = x+width;
			y2 = y+height;
			XDrawLine(display, scribble,
				ani_gc, x, y, x2, y2);
			break;
		case MW_ANI_RECTANGLE:
			XDrawRectangle(display, scribble,
				ani_gc, x, y, width, height);
			break;
		case MW_ANI_ARC:
			angle1 = 64*90;		/* bogus!!! */
			angle2 = 64*180;
			XDrawArc(display, scribble,
				ani_gc, x, y, width, height,
				angle1, angle2);
			break;
		case MW_ANI_ELLIPSE:
			XDrawArc(display, scribble,
				ani_gc, x, y, width, height,
				0, 64*360);
			break;
		case MW_ANI_PIXMAP:
			img = name2image(w, actor->string);
			if (!img) break;

			XGetGeometry(display, img->pixmap, &root, &x1, &y1,
				&w1, &h1, &b1, &d1);
			XSetClipOrigin(display, ani_gc, x, y);
			XSetClipMask(display, ani_gc, img->mask);

			XCopyArea(display, img->pixmap,
				scribble, ani_gc,
				0, 0, w1, h1, x, y);
			break;
		case MW_ANI_STRING:
			/* set font */
			if (!actor->string) break;	/* sanity */
			p = MwRcMakerich(actor->string, actor->fmt);
			MwRcStrdraw(scribble, ani_gc, 0, 0, x, y, p, -1, 1.0);
			MwFree(p);
			break;
		case MW_ANI_POINT:
			XDrawPoint(display, scribble,
				ani_gc, x, y);
			break;
		case MW_ANI_FILLRECT:
			XFillRectangle(display, scribble,
				ani_gc, x, y, width, height);
			break;
		case MW_ANI_FILLARC:
			angle1 = 64*90;		/* bogus!!! */
			angle2 = 64*180;
			XFillArc(display, scribble,
				ani_gc, x, y, width, height,
				angle1, angle2);
			break;
		case MW_ANI_FILLELLIPSE:
			XFillArc(display, scribble,
				ani_gc, x, y, width, height,
				0, 64*360);
			break;
		default:
			fprintf(stderr, "bzz\n");
		}
	}

	return scribble;
}
示例#15
0
 inline mopo_float SmoothValue::tick() {
   value_ = INTERPOLATE(value_, target_value_, decay_);
   return value_;
 }
示例#16
0
void label_contour(
    double **data,
    long nx,
    long ny,
    double value,
    char *string,
    double xmin,
    double dx,
    double ymin,
    double dy,
    double error_limit,
    long label_mode  
    )
{
/* long label_mode    0 -> on contours,  1 -> around border */
    register double distance, best_distance, nbest_distance;
    register long iy;
    long ix, ix_best, iy_best, ix_nbest=0, iy_nbest=0, n_data;
    double x, y, xmax, ymax, i_int;
    double xd, yd;
    double hoff, voff;

    xmax = xmin + dx*(nx-1);
    ymax = ymin + dy*(ny-1);

    if (label_mode==0) {
        distance = best_distance = 1.0E37;
        ix_best = iy_best = -1;
        n_data = nx*ny;
    
        for (ix=1; ix<nx-2; ix++) {
            for (iy=1; iy<ny-2; iy++) {
                distance = fabs(value - data[ix][iy])/error_limit;
                if (distance<1) {
                    distance += sqr((ix-nx/2.)/nx)+sqr((iy-ny/2.)/ny);
                    if (distance<best_distance) {
                        ix_nbest = ix_best; 
                        iy_nbest = iy_best;
                        nbest_distance = best_distance;
                        ix_best = ix;
                        iy_best = iy;
                        best_distance = distance;
                        }
                    }
                }
            }
        ix = ix_best;
        iy = iy_best;
    
        if (ix==-1) {
            ix = 0;
            for (iy=1; iy<ny-2; iy++) {
                distance = fabs(value - data[ix][iy])/error_limit;
                if (distance<1) {
                    distance += sqr((ix-nx/2.)/nx)+sqr((iy-ny/2.)/ny);
                    if (distance<best_distance) {
                        ix_nbest = ix_best; 
                        iy_nbest = iy_best;
                        nbest_distance = best_distance;
                        ix_best = ix;
                        iy_best = iy;
                        best_distance = distance;
                        }
                    }
                }
            if (ix_best==-1) {
                printf("note: failed to find acceptable contour to label for value %e\n", value);
                return;
                }
            ix = ix_best;
            iy = iy_best;
            }

        if (fabs(value-data[ix][iy])>error_limit)
            bomb("algorithmic error (1) in label_contour()", NULL);
    
        x = dx*ix + xmin;
        y = dy*iy + ymin;
        if (ix<nx-1 && data[ix][iy]!=data[ix+1][iy])
            x += dx*(value-data[ix][iy])/(data[ix+1][iy]-data[ix][iy]);
        else if (iy<ny-1 && data[ix][iy]!=data[ix][iy+1])
            y += dy*(value-data[ix][iy])/(data[ix][iy+1]-data[ix][iy]);
    
        if (x>=xmax-dx/2 || y>=ymax-dy/2 || x<xmin+dx/4 || y<ymin+dy/4) {
            ix = ix_nbest;
            iy = iy_nbest;
            if (ix!=-1) {
                x = dx*ix + xmin;
                y = dy*iy + ymin;
                if (ix<nx-1 && data[ix][iy]!=data[ix+1][iy])
                    x += dx*(value-data[ix][iy])/(data[ix+1][iy]-data[ix][iy]);
                else if (iy<ny-1 && data[ix][iy]!=data[ix][iy+1])
                    y += dy*(value-data[ix][iy])/(data[ix][iy+1]-data[ix][iy]);
                if (x>=xmax-dx/2 || y>=ymax-dy/2 || x<xmin+dx/4 || y<ymin+dy/4) {
                    printf("note: label algorithm went outside plot region for value %e\n", value);
                    return;
                    }
                }
            else {
                printf("note: label algorithm went outside plot region for value %e\n", value);
                return;
                }
            }

        xd = x;
        yd = y;
        plot_string(&xd, &yd, string);
        }
    else {
        distance = best_distance = 1.0E37;
        vertical_print(1);

        /* search for end of contour along top edge */
        iy = ny-1;
        get_char_size(&hoff, &voff, 1);
        for (ix=nx-1; ix>0; ix--) {
            if ((data[ix][iy]<value && data[(ix-1)][iy]>=value) ||
                (data[ix][iy]>value && data[(ix-1)][iy]<=value) ) {
                xd = xmin + hoff/3 + dx*(i_int=INTERPOLATE(ix-1, ix, 
                                    data[ix-1][iy], data[ix][iy], value));
                if (i_int>=ix-1 && i_int<=ix) {
                    yd = ymin + (ny-1)*dy + (value>0?voff:voff/2);
                    plot_string(&xd, &yd, string);
                    }
                }
            }
    
        /* search for end of contour along right edge */
        ix = nx-1;
        vertical_print(0);
        get_char_size(&hoff, &voff, 1);
        for (iy=1; iy<ny; iy++) {
            if ((data[ix][iy]<value && value<=data[ix][iy-1]) ||
                (data[ix][iy]>value && value>=data[ix][iy-1]) ) {
                yd = ymin - 2*voff/3 + dy*(i_int=INTERPOLATE(iy-1, iy, 
                                        data[ix][iy-1],
                                        data[ix][iy], value));
                if (!(i_int<iy-1 || i_int>iy)) {
                    xd = xmin + (nx-1)*dx + hoff/2;
                    plot_string(&xd, &yd, string);
                    }
                }
            }
        }
}
示例#17
0
static cairo_surface_t*
rotate (cairo_surface_t *image,
	double           angle,
	gboolean         high_quality,
	guchar           r0,
	guchar           g0,
	guchar           b0,
	guchar           a0,
	GthAsyncTask    *task)
{
	cairo_surface_t *image_with_background;
	cairo_surface_t *rotated;
	double           angle_rad;
	double           cos_angle, sin_angle;
	double           src_width, src_height;
	int              new_width, new_height;
	int              src_rowstride, new_rowstride;
	int              xi, yi;
	double           x, y;
	double           x2, y2;
	int              x2min, y2min;
	int              x2max, y2max;
	double           fx, fy;
	guchar          *p_src, *p_new;
	guchar          *p_src2, *p_new2;
	guchar           r00, r01, r10, r11;
	guchar           g00, g01, g10, g11;
	guchar           b00, b01, b10, b11;
	guchar           a00, a01, a10, a11;
	double           half_new_width;
	double           half_new_height;
	double           half_src_width;
	double           half_src_height;
	int              tmp;
	guchar           r, g, b, a;
	guint32          pixel;

	angle = CLAMP (angle, -90.0, 90.0);
	angle_rad = angle / 180.0 * G_PI;
	cos_angle = cos (angle_rad);
	sin_angle = sin (angle_rad);
	src_width  = cairo_image_surface_get_width  (image);
	src_height = cairo_image_surface_get_height (image);
	new_width  = GDOUBLE_ROUND_TO_INT (      cos_angle  * src_width + fabs(sin_angle) * src_height);
	new_height = GDOUBLE_ROUND_TO_INT (fabs (sin_angle) * src_width +      cos_angle  * src_height);

	if (a0 == 0xff) {
		/* pre-multiply the background color */

		image_with_background = _cairo_image_surface_copy (image);
		p_src = _cairo_image_surface_flush_and_get_data (image);
		p_new = _cairo_image_surface_flush_and_get_data (image_with_background);
		src_rowstride = cairo_image_surface_get_stride (image);
		new_rowstride = cairo_image_surface_get_stride (image_with_background);

		cairo_surface_flush (image_with_background);
		for (yi = 0; yi < src_height; yi++) {
			p_src2 = p_src;
			p_new2 = p_new;
			for (xi = 0; xi < src_width; xi++) {
				a = p_src2[CAIRO_ALPHA];
				r = p_src2[CAIRO_RED] + _cairo_multiply_alpha (r0, 0xff - a);
				g = p_src2[CAIRO_GREEN] + _cairo_multiply_alpha (g0, 0xff - a);
				b = p_src2[CAIRO_BLUE] + _cairo_multiply_alpha (b0, 0xff - a);
				pixel = CAIRO_RGBA_TO_UINT32 (r, g, b, 0xff);
				memcpy (p_new2, &pixel, sizeof (guint32));

				p_new2 += 4;
				p_src2 += 4;
			}
			p_src += src_rowstride;
			p_new += new_rowstride;
		}
		cairo_surface_mark_dirty (image_with_background);
	}
	else
		image_with_background = cairo_surface_reference (image);

	/* create the rotated image */

	rotated = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, new_width, new_height);

	p_src = _cairo_image_surface_flush_and_get_data (image_with_background);
	p_new = _cairo_image_surface_flush_and_get_data (rotated);
	src_rowstride = cairo_image_surface_get_stride (image_with_background);
	new_rowstride = cairo_image_surface_get_stride (rotated);

/*
 * bilinear interpolation
 *            fx
 *    v00------------v01
 *    |        |      |
 * fy |--------v      |
 *    |               |
 *    |               |
 *    |               |
 *    v10------------v11
 */
#define INTERPOLATE(v, v00, v01, v10, v11, fx, fy) \
	tmp = (1.0 - (fy)) * \
	      ((1.0 - (fx)) * (v00) + (fx) * (v01)) \
              + \
              (fy) * \
              ((1.0 - (fx)) * (v10) + (fx) * (v11)); \
	v = CLAMP (tmp, 0, 255);

#define GET_VALUES(r, g, b, a, x, y) \
	if (x >= 0 && x < src_width && y >= 0 && y < src_height) { \
		p_src2 = p_src + src_rowstride * y + 4 * x; \
		r = p_src2[CAIRO_RED]; \
		g = p_src2[CAIRO_GREEN]; \
		b = p_src2[CAIRO_BLUE]; \
		a = p_src2[CAIRO_ALPHA]; \
	} \
	else { \
		r = r0; \
		g = g0; \
		b = b0; \
		a = a0; \
	}

	half_new_width = new_width / 2.0;
	half_new_height = new_height / 2.0;
	half_src_width = src_width / 2.0;
	half_src_height = src_height / 2.0;

	cairo_surface_flush (rotated);

	y = - half_new_height;
	for (yi = 0; yi < new_height; yi++) {
		if (task != NULL) {
			gboolean cancelled;
			double   progress;

			gth_async_task_get_data (task, NULL, &cancelled, NULL);
			if (cancelled)
				goto out;

			progress = (double) yi / new_height;
			gth_async_task_set_data (task, NULL, NULL, &progress);
		}

		p_new2 = p_new;

		x = - half_new_width;
		for (xi = 0; xi < new_width; xi++) {
			x2 = cos_angle * x - sin_angle * y + half_src_width;
			y2 = sin_angle * x + cos_angle * y + half_src_height;

			if (high_quality) {
				/* Bilinear interpolation. */

				x2min = (int) x2;
				y2min = (int) y2;
				x2max = x2min + 1;
				y2max = y2min + 1;

				GET_VALUES (r00, g00, b00, a00, x2min, y2min);
				GET_VALUES (r01, g01, b01, a01, x2max, y2min);
				GET_VALUES (r10, g10, b10, a10, x2min, y2max);
				GET_VALUES (r11, g11, b11, a11, x2max, y2max);

				fx = x2 - x2min;
				fy = y2 - y2min;

				INTERPOLATE (r, r00, r01, r10, r11, fx, fy);
				INTERPOLATE (g, g00, g01, g10, g11, fx, fy);
				INTERPOLATE (b, b00, b01, b10, b11, fx, fy);
				INTERPOLATE (a, a00, a01, a10, a11, fx, fy);

				pixel = CAIRO_RGBA_TO_UINT32 (r, g, b, a);
				memcpy (p_new2, &pixel, sizeof (guint32));
			}
			else {
				/* Nearest neighbor */

				x2min = GDOUBLE_ROUND_TO_INT (x2);
				y2min = GDOUBLE_ROUND_TO_INT (y2);

				GET_VALUES (p_new2[CAIRO_RED],
					    p_new2[CAIRO_GREEN],
					    p_new2[CAIRO_BLUE],
					    p_new2[CAIRO_ALPHA],
					    x2min,
					    y2min);
			}

			p_new2 += 4;
			x += 1.0;
		}

		p_new += new_rowstride;
		y += 1.0;
	}

	out:

	cairo_surface_mark_dirty (rotated);
	cairo_surface_destroy (image_with_background);

#undef INTERPOLATE
#undef GET_VALUES

	return rotated;
}
示例#18
0
void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch, 
		   uint8_t *dst, uint32_t dst_pitch,
		   uint32_t width, uint32_t height, int sbpp) {

	unsigned int x, y;
	uint32_t color[16];

	/* Point to the first 3 lines. */
	src_line[0] = src;
	src_line[1] = src;
	src_line[2] = src + src_pitch;
	src_line[3] = src + src_pitch * 2;
	
	x = 0, y = 0;
	
	if (PixelsPerMask == 2) {
		unsigned short *sbp;
		sbp = (unsigned short*)src_line[0];
		color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = color[0];   color[5] = color[0];   color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
		sbp = (unsigned short*)src_line[2];
		color[8] = *sbp;     color[9] = color[8];     color[10] = *(sbp + 1); color[11] = *(sbp + 2);
		sbp = (unsigned short*)src_line[3];
		color[12] = *sbp;    color[13] = color[12];   color[14] = *(sbp + 1); color[15] = *(sbp + 2);
	}
	else {
		uint32_t *lbp;
		lbp = (uint32_t*)src_line[0];
		color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = color[0];   color[5] = color[0];   color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
		lbp = (uint32_t*)src_line[2];
		color[8] = *lbp;     color[9] = color[8];     color[10] = *(lbp + 1); color[11] = *(lbp + 2);
		lbp = (uint32_t*)src_line[3];
		color[12] = *lbp;    color[13] = color[12];   color[14] = *(lbp + 1); color[15] = *(lbp + 2);
	}

	for (y = 0; y < height; y++) {

		dst_line[0] = dst + dst_pitch*2*y;
		dst_line[1] = dst + dst_pitch*(2*y+1);
	
		/* Todo: x = width - 2, x = width - 1 */
		
		for (x = 0; x < width; x++) {
			uint32_t product1a, product1b, product2a, product2b;

//---------------------------------------  B0 B1 B2 B3    0  1  2  3
//                                         4  5* 6  S2 -> 4  5* 6  7
//                                         1  2  3  S1    8  9 10 11
//                                         A0 A1 A2 A3   12 13 14 15
//--------------------------------------
			if (color[9] == color[6] && color[5] != color[10]) {
				product2b = color[9];
				product1b = product2b;
			}
			else if (color[5] == color[10] && color[9] != color[6]) {
				product2b = color[5];
				product1b = product2b;
			}
			else if (color[5] == color[10] && color[9] == color[6]) {
				int r = 0;

				r += GET_RESULT(color[6], color[5], color[8], color[13]);
				r += GET_RESULT(color[6], color[5], color[4], color[1]);
				r += GET_RESULT(color[6], color[5], color[14], color[11]);
				r += GET_RESULT(color[6], color[5], color[2], color[7]);

				if (r > 0)
					product1b = color[6];
				else if (r < 0)
					product1b = color[5];
				else
					product1b = INTERPOLATE(color[5], color[6]);
					
				product2b = product1b;

			}
			else {
				if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
					product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
				else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
					product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
				else
					product2b = INTERPOLATE(color[9], color[10]);

				if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
					product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
				else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
					product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
				else
					product1b = INTERPOLATE(color[5], color[6]);
			}

			if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
				product2a = INTERPOLATE(color[9], color[5]);
			else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
				product2a = INTERPOLATE(color[9], color[5]);
			else
				product2a = color[9];

			if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
				product1a = INTERPOLATE(color[9], color[5]);
			else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
				product1a = INTERPOLATE(color[9], color[5]);
			else
				product1a = color[5];
	
			if (PixelsPerMask == 2) {
				*((uint32_t *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
				*((uint32_t *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
			}
			else {
				*((uint32_t *) (&dst_line[0][x * 8])) = product1a;
				*((uint32_t *) (&dst_line[0][x * 8 + 4])) = product1b;
				*((uint32_t *) (&dst_line[1][x * 8])) = product2a;
				*((uint32_t *) (&dst_line[1][x * 8 + 4])) = product2b;
			}
			
			/* Move color matrix forward */
			color[0] = color[1]; color[4] = color[5]; color[8] = color[9];   color[12] = color[13];
			color[1] = color[2]; color[5] = color[6]; color[9] = color[10];  color[13] = color[14];
			color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
			
			if (x < width - 3) {
				x += 3;
				if (PixelsPerMask == 2) {
					color[3] = *(((unsigned short*)src_line[0]) + x);					
					color[7] = *(((unsigned short*)src_line[1]) + x);
					color[11] = *(((unsigned short*)src_line[2]) + x);
					color[15] = *(((unsigned short*)src_line[3]) + x);
				}
				else {
					color[3] = *(((uint32_t*)src_line[0]) + x);
					color[7] = *(((uint32_t*)src_line[1]) + x);
					color[11] = *(((uint32_t*)src_line[2]) + x);
					color[15] = *(((uint32_t*)src_line[3]) + x);
				}
				x -= 3;
			}
		}

		/* We're done with one line, so we shift the source lines up */
		src_line[0] = src_line[1];
		src_line[1] = src_line[2];
		src_line[2] = src_line[3];		

		/* Read next line */
		if (y + 3 >= height)
			src_line[3] = src_line[2];
		else
			src_line[3] = src_line[2] + src_pitch;
			
		/* Then shift the color matrix up */
		if (PixelsPerMask == 2) {
			unsigned short *sbp;
			sbp = (unsigned short*)src_line[0];
			color[0] = *sbp;     color[1] = color[0];    color[2] = *(sbp + 1);  color[3] = *(sbp + 2);
			sbp = (unsigned short*)src_line[1];
			color[4] = *sbp;     color[5] = color[4];    color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
			sbp = (unsigned short*)src_line[2];
			color[8] = *sbp;     color[9] = color[9];    color[10] = *(sbp + 1); color[11] = *(sbp + 2);
			sbp = (unsigned short*)src_line[3];
			color[12] = *sbp;    color[13] = color[12];  color[14] = *(sbp + 1); color[15] = *(sbp + 2);
		}
		else {
			uint32_t *lbp;
			lbp = (uint32_t*)src_line[0];
			color[0] = *lbp;     color[1] = color[0];    color[2] = *(lbp + 1);  color[3] = *(lbp + 2);
			lbp = (uint32_t*)src_line[1];
			color[4] = *lbp;     color[5] = color[4];    color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
			lbp = (uint32_t*)src_line[2];
			color[8] = *lbp;     color[9] = color[9];    color[10] = *(lbp + 1); color[11] = *(lbp + 2);
			lbp = (uint32_t*)src_line[3];
			color[12] = *lbp;    color[13] = color[12];  color[14] = *(lbp + 1); color[15] = *(lbp + 2);
		}
		
	} // y loop
	
}
示例#19
0
gint
main (gint    argc,
      gchar **argv)
{
  gegl_init (&argc, &argv);  /* initialize the GEGL library */

  /* license for this application, needed by fractal-explorer */
  g_object_set (gegl_config (),
                "application-license", "GPL3",
                NULL);

  {
    /* instantiate a graph */
    GeglNode *gegl = gegl_node_new ();

/*
This is the graph we're going to construct:

.-----------.
| display   |
`-----------'
    |
.--------.
|  crop  |
`--------'
    |
.--------.
|  over  |
`--------'
    |   \
    |    \
    |     \
    |      |
    |   .------.
    |   | text |
    |   `------'
.------------------.
| fractal-explorer |
`------------------'

*/

    /*< The image nodes representing operations we want to perform */
    GeglNode *display    = gegl_node_create_child (gegl, "gegl:ff-save");
    GeglNode *crop       = gegl_node_new_child (gegl,
                                 "operation", "gegl:crop",
                                 "width", 512.0,
                                 "height", 384.0,
                                  NULL);
    GeglNode *over       = gegl_node_new_child (gegl,
                                 "operation", "gegl:over",
                                 NULL);
    GeglNode *text       = gegl_node_new_child (gegl,
                                 "operation", "gegl:text",
                                 "size", 10.0,
                                 "color", gegl_color_new ("rgb(1.0,1.0,1.0)"),
                                 NULL);
    GeglNode *mandelbrot = gegl_node_new_child (gegl,
                                "operation", "gegl:fractal-explorer",
                                "shiftx", -256.0,
                                NULL);

    gegl_node_link_many (mandelbrot, over, crop, display, NULL);
    gegl_node_connect_to (text, "output",  over, "aux");

    /* request that the save node is processed, all dependencies will
     * be processed as well
     */
    {
      gint frame;
      gint frames = 200;

      for (frame=0; frame<frames; frame++)
        {
          gchar string[512];
          gdouble t = frame * 1.0/frames;

#define INTERPOLATE(min,max) ((max)*(t)+(min)*(1.0-t))

          gdouble shiftx = INTERPOLATE(-256.0, -512.0);
          gdouble shifty = INTERPOLATE(0.0,    -256.0);
          gdouble zoom   = INTERPOLATE(300.0,   400.0);

          gegl_node_set (mandelbrot, "shiftx", shiftx,
                                     "shifty", shifty,
                                     "zoom", zoom,
                                     NULL);
          g_sprintf (string, "x=%1.3f y=%1.3f z=%1.3f", shiftx, shifty, zoom);
          gegl_node_set (text, "string", string, NULL);
          gegl_node_process (display);
        }
    }

    /* free resources used by the graph and the nodes it owns */
    g_object_unref (gegl);
  }

  /* free resources globally used by GEGL */
  gegl_exit ();

  return 0;
}