瀏覽代碼

Start writing Visual Studio projects.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2904 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 年之前
父節點
當前提交
4bfa33f1b9
共有 10 個檔案被更改,包括 573 行新增175 行删除
  1. +20
    -0
      libpipi.sln
  2. +17
    -17
      pipi/colorstring.c
  3. +3
    -0
      pipi/dither/ordered.c
  4. +3
    -0
      pipi/filter/blur.c
  5. +5
    -7
      pipi/histogram/histogram.c
  6. +363
    -0
      pipi/libpipi.vcproj
  7. +8
    -8
      pipi/paint/floodfill.c
  8. +86
    -93
      pipi/paint/line.c
  9. +64
    -50
      pipi/quantize/reduce.c
  10. +4
    -0
      pipi/render/screen.c

+ 20
- 0
libpipi.sln 查看文件

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpipi", "pipi\libpipi.vcproj", "{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}.Debug|Win32.ActiveCfg = Debug|Win32
{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}.Debug|Win32.Build.0 = Debug|Win32
{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}.Release|Win32.ActiveCfg = Release|Win32
{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

+ 17
- 17
pipi/colorstring.c 查看文件

@@ -36,31 +36,31 @@ struct color_table

struct color_table color_table[] =
{
{.name = "black" , 1, 0, 0, 0},
{.name = "white" , 1, 1, 1, 1},
{.name = "red" , 1, 1, 0, 0},
{.name = "green" , 1, 0, 1, 0},
{.name = "blue" , 1, 0, 0, 1},
{.name = "yellow" , 1, 1, 1, 0},
{.name = "cyan" , 1, 0, 1, 1},
{.name = "magenta", 1, 1, 0, 1},
{.name = "grey" , 1, 0.5, 0.5, 0.5},
{.name = "gray" , 1, 0.5, 0.5, 0.5},
{.name = "grey50" , 1, 0.5, 0.5, 0.5},
{.name = "gray50" , 1, 0.5, 0.5, 0.5},
{.name = "grey25" , 1, 0.25, 0.25, 0.25},
{.name = "gray25" , 1, 0.25, 0.25, 0.25},
{ "black" , 1, 0, 0, 0 },
{ "white" , 1, 1, 1, 1 },
{ "red" , 1, 1, 0, 0 },
{ "green" , 1, 0, 1, 0 },
{ "blue" , 1, 0, 0, 1 },
{ "yellow" , 1, 1, 1, 0 },
{ "cyan" , 1, 0, 1, 1 },
{ "magenta", 1, 1, 0, 1 },
{ "grey" , 1, 0.5, 0.5, 0.5 },
{ "gray" , 1, 0.5, 0.5, 0.5 },
{ "grey50" , 1, 0.5, 0.5, 0.5 },
{ "gray50" , 1, 0.5, 0.5, 0.5 },
{ "grey25" , 1, 0.25, 0.25, 0.25 },
{ "gray25" , 1, 0.25, 0.25, 0.25 },
};



pipi_pixel_t *pipi_get_color_from_string(const char* s)
{
if(!s) return NULL;

pipi_pixel_t *color;

pipi_pixel_t *color = malloc(sizeof(pipi_pixel_t));
if(!s) return NULL;

color = malloc(sizeof(pipi_pixel_t));

if(s[0] == '#')
{


+ 3
- 0
pipi/dither/ordered.c 查看文件

@@ -20,6 +20,9 @@

#include <stdlib.h>
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif

#include "pipi.h"
#include "pipi_internals.h"


+ 3
- 0
pipi/filter/blur.c 查看文件

@@ -22,6 +22,9 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif

#include "pipi.h"
#include "pipi_internals.h"


+ 5
- 7
pipi/histogram/histogram.c 查看文件

@@ -35,11 +35,14 @@ pipi_histogram_t* pipi_new_histogram(void)

int pipi_get_image_histogram(pipi_image_t *img, pipi_histogram_t*h, int flags)
{
uint8_t *data;
float n;
unsigned int max;
int i;

if(!h) return -1;

uint8_t *data = (uint8_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels;
data = (uint8_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels;

for(i=0; i< img->w*img->h*4; i+=4)
{
@@ -63,9 +66,6 @@ int pipi_get_image_histogram(pipi_image_t *img, pipi_histogram_t*h, int flags)
}

/* Normalize dataset */
unsigned int max;
float n;

if(flags&PIPI_COLOR_R)
{
max = 0;
@@ -112,16 +112,14 @@ int pipi_get_image_histogram(pipi_image_t *img, pipi_histogram_t*h, int flags)
h->y[i]*=n;
}


return 0;
}

int pipi_render_histogram(pipi_image_t *img, pipi_histogram_t*h, int flags)
{
if(!img || !h) return -1;

int x;

if(!img || !h) return -1;

for(x=0; x<256; x++)
{


+ 363
- 0
pipi/libpipi.vcproj 查看文件

@@ -0,0 +1,363 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="libpipi"
ProjectGUID="{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\win32;.;.."
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPIPI_EXPORTS;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\win32;.;.."
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPIPI_EXPORTS;"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\win32\config.h"
>
</File>
<File
RelativePath=".\pipi.h"
>
</File>
<File
RelativePath=".\pipi_internals.h"
>
</File>
<File
RelativePath=".\pipi_stubs.h"
>
</File>
<File
RelativePath=".\pipi_template.h"
>
</File>
<File
RelativePath="..\win32\pipi_types.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\accessors.c"
>
</File>
<File
RelativePath=".\filter\autocontrast.c"
>
</File>
<File
RelativePath=".\paint\bezier.c"
>
</File>
<File
RelativePath=".\filter\blur.c"
>
</File>
<File
RelativePath=".\codec.c"
>
</File>
<File
RelativePath=".\filter\color.c"
>
</File>
<File
RelativePath=".\colorstring.c"
>
</File>
<File
RelativePath=".\context.c"
>
</File>
<File
RelativePath=".\filter\convolution.c"
>
</File>
<File
RelativePath=".\dither\dbs.c"
>
</File>
<File
RelativePath=".\filter\dilate.c"
>
</File>
<File
RelativePath=".\dither.c"
>
</File>
<File
RelativePath=".\dither\ediff.c"
>
</File>
<File
RelativePath=".\paint\floodfill.c"
>
</File>
<File
RelativePath=".\codec\gdi.c"
>
</File>
<File
RelativePath=".\histogram\histogram.c"
>
</File>
<File
RelativePath=".\paint\line.c"
>
</File>
<File
RelativePath=".\combine\mean.c"
>
</File>
<File
RelativePath=".\measure.c"
>
</File>
<File
RelativePath=".\filter\median.c"
>
</File>
<File
RelativePath=".\combine\minmax.c"
>
</File>
<File
RelativePath=".\combine\mulscreen.c"
>
</File>
<File
RelativePath=".\render\noise.c"
>
</File>
<File
RelativePath=".\dither\ordered.c"
>
</File>
<File
RelativePath=".\codec\oric.c"
>
</File>
<File
RelativePath=".\dither\ostromoukhov.c"
>
</File>
<File
RelativePath=".\pipi.c"
>
</File>
<File
RelativePath=".\pixels.c"
>
</File>
<File
RelativePath=".\dither\random.c"
>
</File>
<File
RelativePath=".\quantize\reduce.c"
>
</File>
<File
RelativePath=".\resize.c"
>
</File>
<File
RelativePath=".\combine\rgb.c"
>
</File>
<File
RelativePath=".\render\screen.c"
>
</File>
<File
RelativePath=".\stock.c"
>
</File>
<File
RelativePath=".\combine\subadd.c"
>
</File>
<File
RelativePath=".\paint\tile.c"
>
</File>
<File
RelativePath=".\filter\transform.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

+ 8
- 8
pipi/paint/floodfill.c 查看文件

@@ -124,15 +124,15 @@ void pipi_flood_fill_stack_scanline_u32(pipi_pixels_t *dstp,
int x, int y,
uint32_t new, uint32_t old)
{
if(new==old) return;

clear_stack(dstp->h);

int yt;
int left, right;

uint32_t *dstdata = (uint32_t *)dstp->pixels;

if(new==old) return;

clear_stack(dstp->h);

if(!push(x, y, dstp->h)) return;

while(pop(&x, &y, dstp->h))
@@ -181,14 +181,14 @@ static void pipi_flood_fill_stack_scanline_float(pipi_pixels_t *dstp,
float nr, float ng, float nb, float na,
float or, float og, float ob, float oa)
{
if((nr==or) && (ng==og) && (nb==ob)) return;

clear_stack(dstp->h);

int yt;
int left, right;
float *dstdata = (float *)dstp->pixels;

if((nr==or) && (ng==og) && (nb==ob)) return;

clear_stack(dstp->h);

if(!push(x, y, dstp->h)) return;

while(pop(&x, &y, dstp->h))


+ 86
- 93
pipi/paint/line.c 查看文件

@@ -23,18 +23,11 @@
#include <stdlib.h>
#include <string.h>

#undef __USE_MISC /* THAT sucks */
#undef __USE_XOPEN /* THAT sucks, too (avoid declaring y1 in math.h) */
#include <math.h>

#include "pipi.h"
#include "pipi_internals.h"

/* math.h doesn't like y1 (sucker) */
float floorf(float x);
float truncf(float x);
float fabsf(float x);

#if !defined TEMPLATE_FILE /* This file uses the template system */

static float fractf(float d) { return (d - floorf(d)); }
@@ -42,8 +35,8 @@ static float fractinvf(float d) { return (1 - (d - floorf(d))); }

struct line
{
int x1, y1;
int x2, y2;
int xa, ya;
int xb, yb;
void (*draw) (pipi_image_t*, struct line*);
union {
uint32_t color32;
@@ -64,13 +57,13 @@ struct line
static void clip_line(pipi_image_t*, struct line*);
static uint8_t clip_bits(pipi_image_t*, int, int);

int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t c, int aa)
int pipi_draw_line(pipi_image_t *img , int xa, int ya, int xb, int yb, uint32_t c, int aa)
{
struct line s;
s.x1 = x1;
s.y1 = y1;
s.x2 = x2;
s.y2 = y2;
s.xa = xa;
s.ya = ya;
s.xb = xb;
s.yb = yb;


/* No Transparency routine for u32 yet, fallback to float version */
@@ -138,8 +131,8 @@ static void clip_line(pipi_image_t *img, struct line* s)
{
uint8_t bits1, bits2;

bits1 = clip_bits(img, s->x1, s->y1);
bits2 = clip_bits(img, s->x2, s->y2);
bits1 = clip_bits(img, s->xa, s->ya);
bits2 = clip_bits(img, s->xb, s->yb);

if(bits1 & bits2)
return;
@@ -151,8 +144,8 @@ static void clip_line(pipi_image_t *img, struct line* s)
else
{
int tmp;
tmp = s->x1; s->x1 = s->x2; s->x2 = tmp;
tmp = s->y1; s->y1 = s->y2; s->y2 = tmp;
tmp = s->xa; s->xa = s->xb; s->xb = tmp;
tmp = s->ya; s->ya = s->yb; s->yb = tmp;
clip_line(img, s);
}
return;
@@ -160,25 +153,25 @@ static void clip_line(pipi_image_t *img, struct line* s)

if(bits1 & (1<<0))
{
s->y1 = s->y2 - (s->x2 - 0) * (s->y2 - s->y1) / (s->x2 - s->x1);
s->x1 = 0;
s->ya = s->yb - (s->xb - 0) * (s->yb - s->ya) / (s->xb - s->xa);
s->xa = 0;
}
else if(bits1 & (1<<1))
{
int xmax = img->w - 1;
s->y1 = s->y2 - (s->x2 - xmax) * (s->y2 - s->y1) / (s->x2 - s->x1);
s->x1 = xmax;
s->ya = s->yb - (s->xb - xmax) * (s->yb - s->ya) / (s->xb - s->xa);
s->xa = xmax;
}
else if(bits1 & (1<<2))
{
s->x1 = s->x2 - (s->y2 - 0) * (s->x2 - s->x1) / (s->y2 - s->y1);
s->y1 = 0;
s->xa = s->xb - (s->yb - 0) * (s->xb - s->xa) / (s->yb - s->ya);
s->ya = 0;
}
else if(bits1 & (1<<3))
{
int ymax = img->h - 1;
s->x1 = s->x2 - (s->y2 - ymax) * (s->x2 - s->x1) / (s->y2 - s->y1);
s->y1 = ymax;
s->xa = s->xb - (s->yb - ymax) * (s->xb - s->xa) / (s->yb - s->ya);
s->ya = ymax;
}

clip_line(img, s);
@@ -241,50 +234,50 @@ static uint8_t clip_bits(pipi_image_t *img, int x, int y)

static void T(aaline)(pipi_image_t *img, struct line* s)
{
float x1 = s->x1, y1 = s->y1, x2 = s->x2, y2 = s->y2;
float xa = s->xa, ya = s->ya, xb = s->xb, yb = s->yb;
float g, xd, yd, xgap, xend, yend, xf, yf, val1, val2;
int x, y, ix1, ix2, iy1, iy2;
int x, y, ixa, ixb, iya, iyb;

xd = x2 - x1;
yd = y2 - y1;
xd = xb - xa;
yd = yb - ya;

/* "Horizontal" line (X greater than Y)*/
if (fabsf(xd) > fabsf(yd))
{
if (x1 > x2)
if (xa > xb)
{
float tmp;
tmp = x1; x1 = x2; x2 = tmp;
tmp = y1; y1 = y2; y2 = tmp;
xd = (x2-x1);
yd = (y2-y1);
tmp = xa; xa = xb; xb = tmp;
tmp = ya; ya = yb; yb = tmp;
xd = (xb-xa);
yd = (yb-ya);
}
g = yd/xd;

xend = truncf(x1+0.5);
yend = y1 + g*(xend-x1);
xgap = fractinvf(x1+0.5);
ix1 = (int)xend;
iy1 = (int)yend;
xend = (float)(int)(xa+0.5);
yend = ya + g*(xend-xa);
xgap = fractinvf(xa+0.5);
ixa = (int)xend;
iya = (int)yend;
val1 = fractinvf(yend)*xgap;
val2 = fractf(yend)*xgap;

PLOT(ix1, iy1, val1);
PLOT(ix1, (iy1+1)<y1?(iy1+1):iy1, val2);
PLOT(ixa, iya, val1);
PLOT(ixa, (iya+1)<ya?(iya+1):iya, val2);

yf = yend+g;
xend = truncf(x2+0.5);
yend = y2 + g*(xend-x2);
xgap = fractinvf(x2-0.5);
ix2 = (int)xend;
iy2 = (int)yend;
xend = (float)(int)(xb+0.5);
yend = yb + g*(xend-xb);
xgap = fractinvf(xb-0.5);
ixb = (int)xend;
iyb = (int)yend;
val1 = fractinvf(yend)*xgap;
val2 = fractf(yend)*xgap;

PLOT(ix2, iy2, val1);
PLOT(ix2, iy2+1<y2?iy2+1:iy2, val2);
PLOT(ixb, iyb, val1);
PLOT(ixb, iyb+1<yb?iyb+1:iyb, val2);

for (x = (ix1+1); x < ix2; x++)
for (x = (ixa+1); x < ixb; x++)
{
float focus;

@@ -295,7 +288,7 @@ static void T(aaline)(pipi_image_t *img, struct line* s)
val2 += 0.3*focus;

PLOT(x, yf, val1);
PLOT(x, (yf+1)<y1?(yf+1):yf, val2);
PLOT(x, (yf+1)<ya?(yf+1):yf, val2);

yf = yf + g;
}
@@ -303,43 +296,43 @@ static void T(aaline)(pipi_image_t *img, struct line* s)
/* "Vertical" line (Y greater than X)*/
else
{
if (x1 > x2)
if (xa > xb)
{
float tmp;
tmp = x1; x1 = x2; x2 = tmp;
tmp = y1; y1 = y2; y2 = tmp;
xd = (x2-x1);
yd = (y2-y1);
tmp = xa; xa = xb; xb = tmp;
tmp = ya; ya = yb; yb = tmp;
xd = (xb-xa);
yd = (yb-ya);
}

g = xd/yd;

xend = truncf(x1+0.5);
yend = y1 + g*(xend-x1);
xgap = fractf(x1+0.5);
ix1 = (int)xend;
iy1 = (int)yend;
xend = (float)(int)(xa+0.5);
yend = ya + g*(xend-xa);
xgap = fractf(xa+0.5);
ixa = (int)xend;
iya = (int)yend;
val1 = fractinvf(yend)*xgap;
val2 = fractf(yend)*xgap;

PLOT(ix1, iy1, val1);
PLOT(ix1, (iy1+1)<y1?(iy1+1):iy1, val2);
PLOT(ixa, iya, val1);
PLOT(ixa, (iya+1)<ya?(iya+1):iya, val2);

xf = xend + g;

xend = truncf(x2+0.5);
yend = y2 + g*(xend-x2);
xgap = fractinvf(x2-0.5);
ix2 = (int)xend;
iy2 = (int)yend;
xend = (float)(int)(xb+0.5);
yend = yb + g*(xend-xb);
xgap = fractinvf(xb-0.5);
ixb = (int)xend;
iyb = (int)yend;
val1 = fractinvf(yend)*xgap;
val2 = fractf(yend)*xgap;

PLOT(ix2, iy2, val1);
PLOT(ix2, (iy2+1)<y2?(iy2+1):iy2, val2);
PLOT(ixb, iyb, val1);
PLOT(ixb, (iyb+1)<yb?(iyb+1):iyb, val2);


for (y = (iy1+1); y < iy2; y++)
for (y = (iya+1); y < iyb; y++)
{
float focus;
int vx = xf;
@@ -362,17 +355,17 @@ static void T(aaline)(pipi_image_t *img, struct line* s)
* scan-conversion algorithm. */
static void T(line)(pipi_image_t *img, struct line* s)
{
int x1, y1, x2, y2;
int xa, ya, xb, yb;
int dx, dy;
int xinc, yinc;

x1 = s->x1; y1 = s->y1; x2 = s->x2; y2 = s->y2;
xa = s->xa; ya = s->ya; xb = s->xb; yb = s->yb;

dx = abs(x2 - x1);
dy = abs(y2 - y1);
dx = abs(xb - xa);
dy = abs(yb - ya);

xinc = (x1 > x2) ? -1 : 1;
yinc = (y1 > y2) ? -1 : 1;
xinc = (xa > xb) ? -1 : 1;
yinc = (ya > yb) ? -1 : 1;

if(dx >= dy)
{
@@ -387,29 +380,29 @@ static void T(line)(pipi_image_t *img, struct line* s)
if(FLAG_8BIT)
/* TODO */;
else
s->buf_f[x1 + y1 * img->w] = s->colorf[0];
s->buf_f[xa + ya * img->w] = s->colorf[0];
}
else
{
if(FLAG_8BIT)
s->buf_u32[x1 + y1 * img->w] = s->color32;
s->buf_u32[xa + ya * img->w] = s->color32;
else
{
s->buf_f[4 * (y1 * img->w + x1)] = s->colorf[0];
s->buf_f[4 * (y1 * img->w + x1) + 1] = s->colorf[1];
s->buf_f[4 * (y1 * img->w + x1) + 2] = s->colorf[2];
s->buf_f[4 * (ya * img->w + xa)] = s->colorf[0];
s->buf_f[4 * (ya * img->w + xa) + 1] = s->colorf[1];
s->buf_f[4 * (ya * img->w + xa) + 2] = s->colorf[2];
}
}

if(delta > 0)
{
x1 += xinc;
y1 += yinc;
xa += xinc;
ya += yinc;
delta += dpru;
}
else
{
x1 += xinc;
xa += xinc;
delta += dpr;
}
}
@@ -427,29 +420,29 @@ static void T(line)(pipi_image_t *img, struct line* s)
if(FLAG_8BIT)
/* TODO */;
else
s->buf_f[x1 + y1 * img->w] = s->colorf[0];
s->buf_f[xa + ya * img->w] = s->colorf[0];
}
else
{
if(FLAG_8BIT)
s->buf_u32[x1 + y1 * img->w] = s->color32;
s->buf_u32[xa + ya * img->w] = s->color32;
else
{
s->buf_f[4 * (y1 * img->w + x1)] = s->colorf[0];
s->buf_f[4 * (y1 * img->w + x1) + 1] = s->colorf[1];
s->buf_f[4 * (y1 * img->w + x1) + 2] = s->colorf[2];
s->buf_f[4 * (ya * img->w + xa)] = s->colorf[0];
s->buf_f[4 * (ya * img->w + xa) + 1] = s->colorf[1];
s->buf_f[4 * (ya * img->w + xa) + 2] = s->colorf[2];
}
}

if(delta > 0)
{
x1 += xinc;
y1 += yinc;
xa += xinc;
ya += yinc;
delta += dpru;
}
else
{
y1 += yinc;
ya += yinc;
delta += dpr;
}
}


+ 64
- 50
pipi/quantize/reduce.c 查看文件

@@ -22,8 +22,12 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif

#include <pipi.h>
#include "pipi.h"
#include "pipi_internals.h"

#define R 0
#define G 1
@@ -32,9 +36,6 @@
#define Y 4
#define A 5

//#define debug printf
#define debug(...) /* */

#define BRIGHT(x) (0.299*(x)[0] + 0.587*(x)[1] + 0.114*(x)[2])

#define MAXCOLORS 16
@@ -80,15 +81,17 @@ static void init_uv(void)
*/
static hull_t *compute_hull(int ncolors, double const *palette)
{
double pal[MAXCOLORS][3];
double gray[3];
double *dark = NULL, *light = NULL;
double tmp, min = 1.0, max = 0.0;
hull_t *ret = malloc(sizeof(hull_t));
double tmp;
int i, j;
int i, j, n;

debug("\n### NEW HULL ###\n\n");

debug("Analysing %i colors\n", ncolors);

double pal[ncolors][3];
for(i = 0; i < ncolors; i++)
{
pal[i][R] = palette[i * 3];
@@ -100,8 +103,6 @@ static hull_t *compute_hull(int ncolors, double const *palette)
/*
* 1. Find the darkest and lightest colours
*/
double *dark = NULL, *light = NULL;
double min = 1.0, max = 0.0;
for(i = 0; i < ncolors; i++)
{
double p = BRIGHT(pal[i]);
@@ -117,8 +118,6 @@ static hull_t *compute_hull(int ncolors, double const *palette)
}
}

double gray[3];

gray[R] = light[R] - dark[R];
gray[G] = light[G] - dark[G];
gray[B] = light[B] - dark[B];
@@ -129,20 +128,20 @@ static hull_t *compute_hull(int ncolors, double const *palette)
/*
* 3. Browse the grey axis and do stuff
*/
int n;
for(n = 0; n <= STEPS; n++)
{
double pts[ncolors * (ncolors - 1) / 2][5];
double pts[MAXCOLORS * (MAXCOLORS - 1) / 2][5];
double ptmp[5];
double p0[3];
#define SWAP(p1,p2) do { memcpy(ptmp, p1, sizeof(ptmp)); \
memcpy(p1, p2, sizeof(ptmp)); \
memcpy(p2, ptmp, sizeof(ptmp)); } while(0)
double ctx, cty, weight;
double t = n * 1.0 / STEPS;
int npts = 0;
int npts = 0, left;

debug("Slice %i/%i\n", n, STEPS);

double p0[3];
p0[R] = dark[R] + t * gray[R];
p0[G] = dark[G] + t * gray[G];
p0[B] = dark[B] + t * gray[B];
@@ -155,37 +154,39 @@ static hull_t *compute_hull(int ncolors, double const *palette)
for(i = 0; i < ncolors; i++)
{
double k1[3];
double yk1;
k1[R] = pal[i][R] - p0[R];
k1[G] = pal[i][G] - p0[G];
k1[B] = pal[i][B] - p0[B];
tmp = sqrt(k1[R] * k1[R] + k1[G] * k1[G] + k1[B] * k1[B]);

/* If k1.y > t.y.y, we don't want this point */
double yk1 = y[R] * k1[R] + y[G] * k1[G] + y[B] * k1[B];
yk1 = y[R] * k1[R] + y[G] * k1[G] + y[B] * k1[B];
if(yk1 > t * ylen * ylen + EPSILON)
continue;

for(j = 0; j < ncolors; j++)
{
if(i == j)
double k2[3];
double yk2, s;

if(i == j)
continue;

double k2[3];
k2[R] = pal[j][R] - p0[R];
k2[G] = pal[j][G] - p0[G];
k2[B] = pal[j][B] - p0[B];
tmp = sqrt(k2[R] * k2[R] + k2[G] * k2[G] + k2[B] * k2[B]);

/* If k2.y < t.y.y, we don't want this point */
double yk2 = y[R] * k2[R] + y[G] * k2[G] + y[B] * k2[B];
yk2 = y[R] * k2[R] + y[G] * k2[G] + y[B] * k2[B];
if(yk2 < t * ylen * ylen - EPSILON)
continue;

if(yk2 < yk1)
continue;

double s = yk1 == yk2 ?
0.5 : (t * ylen * ylen - yk1) / (yk2 - yk1);
s = yk1 == yk2 ? 0.5 : (t * ylen * ylen - yk1) / (yk2 - yk1);

pts[npts][R] = p0[R] + k1[R] + s * (k2[R] - k1[R]);
pts[npts][G] = p0[G] + k1[G] + s * (k2[G] - k1[G]);
@@ -211,7 +212,7 @@ static hull_t *compute_hull(int ncolors, double const *palette)
}

/* Find the leftmost point */
int left = -1;
left = -1;
tmp = 10.;
for(i = 0; i < npts; i++)
if(pts[i][X] < tmp)
@@ -248,15 +249,17 @@ static hull_t *compute_hull(int ncolors, double const *palette)
/* Remove points not in the convex hull */
for(i = 2; i < npts; /* */)
{
double k1, k2;

if(i < 2)
{
i++;
continue;
}

double k1 = (pts[i - 1][X] - pts[i - 2][X])
k1 = (pts[i - 1][X] - pts[i - 2][X])
* (pts[i][Y] - pts[i - 2][Y]);
double k2 = (pts[i][X] - pts[i - 2][X])
k2 = (pts[i][X] - pts[i - 2][X])
* (pts[i - 1][Y] - pts[i - 2][Y]);
if(k1 <= k2 + EPSILON)
{
@@ -273,19 +276,22 @@ static hull_t *compute_hull(int ncolors, double const *palette)
debug(" 2D pt[%i] (%g,%g)\n", i, pts[i][X], pts[i][Y]);

/* Compute the barycentre coordinates */
double ctx = 0., cty = 0., weight = 0.;
ctx = 0.;
cty = 0.;
weight = 0.;
for(i = 2; i < npts; i++)
{
double abx = pts[i - 1][X] - pts[0][X];
double aby = pts[i - 1][Y] - pts[0][Y];
double acx = pts[i][X] - pts[0][X];
double acy = pts[i][Y] - pts[0][Y];
double area;
double sqarea = (abx * abx + aby * aby) * (acx * acx + acy * acy)
- (abx * acx + aby * acy) * (abx * acx + aby * acy);
if(sqarea <= 0.)
continue;

double area = sqrt(sqarea);
area = sqrt(sqarea);
ctx += area * (abx + acx) / 3;
cty += area * (aby + acy) / 3;
weight += area;
@@ -351,12 +357,16 @@ pipi_image_t *pipi_reduce(pipi_image_t *src,
1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1,
};

int i, j;
pipi_image_t *dst;
pipi_pixels_t *srcp, *dstp;
float *srcdata, *dstdata;
hull_t *rgbhull, *myhull;
int i, j, w, h;

init_uv();

hull_t *rgbhull = compute_hull(8, rgbpal);
hull_t *myhull = compute_hull(ncolors, palette);
rgbhull = compute_hull(8, rgbpal);
myhull = compute_hull(ncolors, palette);

/*
* 4. Load image and change its palette.
@@ -364,19 +374,23 @@ pipi_image_t *pipi_reduce(pipi_image_t *src,

debug("\n### PROCESSING IMAGE ###\n\n");

pipi_pixels_t *srcp = pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
float *srcdata = (float *)srcp->pixels;
srcp = pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
srcdata = (float *)srcp->pixels;

int w = srcp->w, h = srcp->h;
w = srcp->w;
h = srcp->h;

pipi_image_t *dst = pipi_new(w, h);
pipi_pixels_t *dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
float *dstdata = (float *)dstp->pixels;
dst = pipi_new(w, h);
dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
dstdata = (float *)dstp->pixels;

for(j = 0; j < h; j++)
for(i = 0; i < w; i++)
{
double p[3];
double xp, yp, angle, xa, ya, xb, yb, t, s;
int slice, n, count;

/* FIXME: Imlib fucks up the RGB order. */
p[B] = srcdata[4 * (j * w + i)];
p[G] = srcdata[4 * (j * w + i) + 1];
@@ -384,17 +398,17 @@ pipi_image_t *pipi_reduce(pipi_image_t *src,

debug("Pixel +%i+%i (%g,%g,%g)\n", i, j, p[R], p[G], p[B]);

int slice = (int)(BRIGHT(p) * STEPS + 0.5);
slice = (int)(BRIGHT(p) * STEPS + 0.5);

debug(" slice %i\n", slice);

/* Convert to 2D. The origin is the slice's barycentre. */
double xp = (p[R] - rgbhull->bary[slice][R]) * u[R]
+ (p[G] - rgbhull->bary[slice][G]) * u[G]
+ (p[B] - rgbhull->bary[slice][B]) * u[B];
double yp = (p[R] - rgbhull->bary[slice][R]) * v[R]
+ (p[G] - rgbhull->bary[slice][G]) * v[G]
+ (p[B] - rgbhull->bary[slice][B]) * v[B];
xp = (p[R] - rgbhull->bary[slice][R]) * u[R]
+ (p[G] - rgbhull->bary[slice][G]) * u[G]
+ (p[B] - rgbhull->bary[slice][B]) * u[B];
yp = (p[R] - rgbhull->bary[slice][R]) * v[R]
+ (p[G] - rgbhull->bary[slice][G]) * v[G]
+ (p[B] - rgbhull->bary[slice][B]) * v[B];

debug(" 2D pt (%g,%g)\n", xp, yp);

@@ -404,8 +418,8 @@ pipi_image_t *pipi_reduce(pipi_image_t *src,
* of having an original colour space other than RGB. */

/* First, find the relevant triangle. */
int n, count = rgbhull->hullsize[slice];
double angle = atan2(yp, xp);
count = rgbhull->hullsize[slice];
angle = atan2(yp, xp);
for(n = 0; n < count; n++)
{
double a1 = rgbhull->pts[slice][n][A];
@@ -423,11 +437,11 @@ pipi_image_t *pipi_reduce(pipi_image_t *src,

/* Now compute the distance to the triangle's edge. If the edge
* intersection is M, then t is such as P = t.M (can be zero) */
double xa = rgbhull->pts[slice][n % count][X];
double ya = rgbhull->pts[slice][n % count][Y];
double xb = rgbhull->pts[slice][(n + 1) % count][X];
double yb = rgbhull->pts[slice][(n + 1) % count][Y];
double t = (xp * (yb - ya) - yp * (xb - xa)) / (xa * yb - xb * ya);
xa = rgbhull->pts[slice][n % count][X];
ya = rgbhull->pts[slice][n % count][Y];
xb = rgbhull->pts[slice][(n + 1) % count][X];
yb = rgbhull->pts[slice][(n + 1) % count][Y];
t = (xp * (yb - ya) - yp * (xb - xa)) / (xa * yb - xb * ya);

if(t > 1.0)
t = 1.0;
@@ -458,7 +472,7 @@ pipi_image_t *pipi_reduce(pipi_image_t *src,
ya = myhull->pts[slice][n % count][Y];
xb = myhull->pts[slice][(n + 1) % count][X];
yb = myhull->pts[slice][(n + 1) % count][Y];
double s = (xp * (yb - ya) - yp * (xb - xa)) / (xa * yb - xb * ya);
s = (xp * (yb - ya) - yp * (xb - xa)) / (xa * yb - xb * ya);

debug(" best custom %g (%g,%g) (%g,%g)\n", s, xa, ya, xb, yb);



+ 4
- 0
pipi/render/screen.c 查看文件

@@ -23,6 +23,10 @@
#include <string.h>
#include <math.h>

#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif

#include "pipi.h"
#include "pipi_internals.h"



Loading…
取消
儲存