Browse Source

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 years ago
parent
commit
4bfa33f1b9
10 changed files with 573 additions and 175 deletions
  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 View File

@@ -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 View File

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


struct color_table 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) 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] == '#') if(s[0] == '#')
{ {


+ 3
- 0
pipi/dither/ordered.c View File

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


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


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


+ 3
- 0
pipi/filter/blur.c View File

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


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


+ 5
- 7
pipi/histogram/histogram.c View File

@@ -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) 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; int i;


if(!h) return -1; 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) 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 */ /* Normalize dataset */
unsigned int max;
float n;

if(flags&PIPI_COLOR_R) if(flags&PIPI_COLOR_R)
{ {
max = 0; 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; h->y[i]*=n;
} }



return 0; return 0;
} }


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

int x; int x;


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


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


+ 363
- 0
pipi/libpipi.vcproj View File

@@ -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 View File

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

clear_stack(dstp->h);

int yt; int yt;
int left, right; int left, right;


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


if(new==old) return;

clear_stack(dstp->h);

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


while(pop(&x, &y, dstp->h)) 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 nr, float ng, float nb, float na,
float or, float og, float ob, float oa) float or, float og, float ob, float oa)
{ {
if((nr==or) && (ng==og) && (nb==ob)) return;

clear_stack(dstp->h);

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


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

clear_stack(dstp->h);

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


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


+ 86
- 93
pipi/paint/line.c View File

@@ -23,18 +23,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.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 <math.h>


#include "pipi.h" #include "pipi.h"
#include "pipi_internals.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 */ #if !defined TEMPLATE_FILE /* This file uses the template system */


static float fractf(float d) { return (d - floorf(d)); } 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 struct line
{ {
int x1, y1;
int x2, y2;
int xa, ya;
int xb, yb;
void (*draw) (pipi_image_t*, struct line*); void (*draw) (pipi_image_t*, struct line*);
union { union {
uint32_t color32; uint32_t color32;
@@ -64,13 +57,13 @@ struct line
static void clip_line(pipi_image_t*, struct line*); static void clip_line(pipi_image_t*, struct line*);
static uint8_t clip_bits(pipi_image_t*, int, int); 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; 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 */ /* 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; 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) if(bits1 & bits2)
return; return;
@@ -151,8 +144,8 @@ static void clip_line(pipi_image_t *img, struct line* s)
else else
{ {
int tmp; 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); clip_line(img, s);
} }
return; return;
@@ -160,25 +153,25 @@ static void clip_line(pipi_image_t *img, struct line* s)


if(bits1 & (1<<0)) 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)) else if(bits1 & (1<<1))
{ {
int xmax = img->w - 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)) 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)) else if(bits1 & (1<<3))
{ {
int ymax = img->h - 1; 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); 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) 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; 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)*/ /* "Horizontal" line (X greater than Y)*/
if (fabsf(xd) > fabsf(yd)) if (fabsf(xd) > fabsf(yd))
{ {
if (x1 > x2)
if (xa > xb)
{ {
float tmp; 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; 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; val1 = fractinvf(yend)*xgap;
val2 = fractf(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; 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; val1 = fractinvf(yend)*xgap;
val2 = fractf(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; float focus;


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


PLOT(x, yf, val1); 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; yf = yf + g;
} }
@@ -303,43 +296,43 @@ static void T(aaline)(pipi_image_t *img, struct line* s)
/* "Vertical" line (Y greater than X)*/ /* "Vertical" line (Y greater than X)*/
else else
{ {
if (x1 > x2)
if (xa > xb)
{ {
float tmp; 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; 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; val1 = fractinvf(yend)*xgap;
val2 = fractf(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; 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; val1 = fractinvf(yend)*xgap;
val2 = fractf(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; float focus;
int vx = xf; int vx = xf;
@@ -362,17 +355,17 @@ static void T(aaline)(pipi_image_t *img, struct line* s)
* scan-conversion algorithm. */ * scan-conversion algorithm. */
static void T(line)(pipi_image_t *img, struct line* s) 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 dx, dy;
int xinc, yinc; 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) if(dx >= dy)
{ {
@@ -387,29 +380,29 @@ static void T(line)(pipi_image_t *img, struct line* s)
if(FLAG_8BIT) if(FLAG_8BIT)
/* TODO */; /* TODO */;
else else
s->buf_f[x1 + y1 * img->w] = s->colorf[0];
s->buf_f[xa + ya * img->w] = s->colorf[0];
} }
else else
{ {
if(FLAG_8BIT) if(FLAG_8BIT)
s->buf_u32[x1 + y1 * img->w] = s->color32;
s->buf_u32[xa + ya * img->w] = s->color32;
else 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) if(delta > 0)
{ {
x1 += xinc;
y1 += yinc;
xa += xinc;
ya += yinc;
delta += dpru; delta += dpru;
} }
else else
{ {
x1 += xinc;
xa += xinc;
delta += dpr; delta += dpr;
} }
} }
@@ -427,29 +420,29 @@ static void T(line)(pipi_image_t *img, struct line* s)
if(FLAG_8BIT) if(FLAG_8BIT)
/* TODO */; /* TODO */;
else else
s->buf_f[x1 + y1 * img->w] = s->colorf[0];
s->buf_f[xa + ya * img->w] = s->colorf[0];
} }
else else
{ {
if(FLAG_8BIT) if(FLAG_8BIT)
s->buf_u32[x1 + y1 * img->w] = s->color32;
s->buf_u32[xa + ya * img->w] = s->color32;
else 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) if(delta > 0)
{ {
x1 += xinc;
y1 += yinc;
xa += xinc;
ya += yinc;
delta += dpru; delta += dpru;
} }
else else
{ {
y1 += yinc;
ya += yinc;
delta += dpr; delta += dpr;
} }
} }


+ 64
- 50
pipi/quantize/reduce.c View File

@@ -22,8 +22,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.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 R 0
#define G 1 #define G 1
@@ -32,9 +36,6 @@
#define Y 4 #define Y 4
#define A 5 #define A 5


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

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


#define MAXCOLORS 16 #define MAXCOLORS 16
@@ -80,15 +81,17 @@ static void init_uv(void)
*/ */
static hull_t *compute_hull(int ncolors, double const *palette) 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)); hull_t *ret = malloc(sizeof(hull_t));
double tmp;
int i, j;
int i, j, n;


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


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


double pal[ncolors][3];
for(i = 0; i < ncolors; i++) for(i = 0; i < ncolors; i++)
{ {
pal[i][R] = palette[i * 3]; 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 * 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++) for(i = 0; i < ncolors; i++)
{ {
double p = BRIGHT(pal[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[R] = light[R] - dark[R];
gray[G] = light[G] - dark[G]; gray[G] = light[G] - dark[G];
gray[B] = light[B] - dark[B]; 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 * 3. Browse the grey axis and do stuff
*/ */
int n;
for(n = 0; n <= STEPS; 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 ptmp[5];
double p0[3];
#define SWAP(p1,p2) do { memcpy(ptmp, p1, sizeof(ptmp)); \ #define SWAP(p1,p2) do { memcpy(ptmp, p1, sizeof(ptmp)); \
memcpy(p1, p2, sizeof(ptmp)); \ memcpy(p1, p2, sizeof(ptmp)); \
memcpy(p2, ptmp, sizeof(ptmp)); } while(0) memcpy(p2, ptmp, sizeof(ptmp)); } while(0)
double ctx, cty, weight;
double t = n * 1.0 / STEPS; double t = n * 1.0 / STEPS;
int npts = 0;
int npts = 0, left;


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


double p0[3];
p0[R] = dark[R] + t * gray[R]; p0[R] = dark[R] + t * gray[R];
p0[G] = dark[G] + t * gray[G]; p0[G] = dark[G] + t * gray[G];
p0[B] = dark[B] + t * gray[B]; 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++) for(i = 0; i < ncolors; i++)
{ {
double k1[3]; double k1[3];
double yk1;
k1[R] = pal[i][R] - p0[R]; k1[R] = pal[i][R] - p0[R];
k1[G] = pal[i][G] - p0[G]; k1[G] = pal[i][G] - p0[G];
k1[B] = pal[i][B] - p0[B]; k1[B] = pal[i][B] - p0[B];
tmp = sqrt(k1[R] * k1[R] + k1[G] * k1[G] + k1[B] * k1[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 */ /* 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) if(yk1 > t * ylen * ylen + EPSILON)
continue; continue;


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

if(i == j)
continue; continue;


double k2[3];
k2[R] = pal[j][R] - p0[R]; k2[R] = pal[j][R] - p0[R];
k2[G] = pal[j][G] - p0[G]; k2[G] = pal[j][G] - p0[G];
k2[B] = pal[j][B] - p0[B]; k2[B] = pal[j][B] - p0[B];
tmp = sqrt(k2[R] * k2[R] + k2[G] * k2[G] + k2[B] * k2[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 */ /* 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) if(yk2 < t * ylen * ylen - EPSILON)
continue; continue;


if(yk2 < yk1) if(yk2 < yk1)
continue; 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][R] = p0[R] + k1[R] + s * (k2[R] - k1[R]);
pts[npts][G] = p0[G] + k1[G] + s * (k2[G] - k1[G]); 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 */ /* Find the leftmost point */
int left = -1;
left = -1;
tmp = 10.; tmp = 10.;
for(i = 0; i < npts; i++) for(i = 0; i < npts; i++)
if(pts[i][X] < tmp) 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 */ /* Remove points not in the convex hull */
for(i = 2; i < npts; /* */) for(i = 2; i < npts; /* */)
{ {
double k1, k2;

if(i < 2) if(i < 2)
{ {
i++; i++;
continue; 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]); * (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]); * (pts[i - 1][Y] - pts[i - 2][Y]);
if(k1 <= k2 + EPSILON) 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]); debug(" 2D pt[%i] (%g,%g)\n", i, pts[i][X], pts[i][Y]);


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


double area = sqrt(sqarea);
area = sqrt(sqarea);
ctx += area * (abx + acx) / 3; ctx += area * (abx + acx) / 3;
cty += area * (aby + acy) / 3; cty += area * (aby + acy) / 3;
weight += area; 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, 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(); 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. * 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"); 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(j = 0; j < h; j++)
for(i = 0; i < w; i++) for(i = 0; i < w; i++)
{ {
double p[3]; double p[3];
double xp, yp, angle, xa, ya, xb, yb, t, s;
int slice, n, count;

/* FIXME: Imlib fucks up the RGB order. */ /* FIXME: Imlib fucks up the RGB order. */
p[B] = srcdata[4 * (j * w + i)]; p[B] = srcdata[4 * (j * w + i)];
p[G] = srcdata[4 * (j * w + i) + 1]; 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]); 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); debug(" slice %i\n", slice);


/* Convert to 2D. The origin is the slice's barycentre. */ /* 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); 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. */ * of having an original colour space other than RGB. */


/* First, find the relevant triangle. */ /* 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++) for(n = 0; n < count; n++)
{ {
double a1 = rgbhull->pts[slice][n][A]; 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 /* 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) */ * 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) if(t > 1.0)
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]; ya = myhull->pts[slice][n % count][Y];
xb = myhull->pts[slice][(n + 1) % count][X]; xb = myhull->pts[slice][(n + 1) % count][X];
yb = myhull->pts[slice][(n + 1) % count][Y]; 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); debug(" best custom %g (%g,%g) (%g,%g)\n", s, xa, ya, xb, yb);




+ 4
- 0
pipi/render/screen.c View File

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


#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif

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




Loading…
Cancel
Save