git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2904 92316355-f0b4-4df1-b90c-862c8a59935fremotes/tiles
| @@ -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 | |||||
| @@ -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] == '#') | ||||
| { | { | ||||
| @@ -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" | ||||
| @@ -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" | ||||
| @@ -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++) | ||||
| { | { | ||||
| @@ -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> | |||||
| @@ -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)) | ||||
| @@ -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; | ||||
| } | } | ||||
| } | } | ||||
| @@ -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); | ||||
| @@ -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" | ||||