mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-28 03:01:17 -06:00
WIP: Moved sources int src/, separated most of the source code from Perl.
The XS was left only for the unit / integration tests, and it links libslic3r only. No wxWidgets are allowed to be used from Perl starting from now.
This commit is contained in:
parent
3ddaccb641
commit
0558b53493
1706 changed files with 7413 additions and 7638 deletions
65
src/CMakeLists.txt
Normal file
65
src/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
project(Slic3r-native)
|
||||
|
||||
add_subdirectory(admesh)
|
||||
add_subdirectory(avrdude)
|
||||
# boost/nowide
|
||||
add_subdirectory(boost)
|
||||
add_subdirectory(clipper)
|
||||
add_subdirectory(miniz)
|
||||
add_subdirectory(polypartition)
|
||||
add_subdirectory(poly2tri)
|
||||
add_subdirectory(qhull)
|
||||
add_subdirectory(Shiny)
|
||||
add_subdirectory(semver)
|
||||
|
||||
# Adding libnest2d project for bin packing...
|
||||
set(LIBNEST2D_UNITTESTS ON CACHE BOOL "Force generating unittests for libnest2d")
|
||||
add_subdirectory(libnest2d)
|
||||
|
||||
include_directories(${LIBDIR}/qhull/src)
|
||||
#message(STATUS ${LIBDIR}/qhull/src)
|
||||
|
||||
|
||||
# ##############################################################################
|
||||
# Configure rasterizer target
|
||||
# ##############################################################################
|
||||
|
||||
find_package(PNG QUIET)
|
||||
|
||||
option(RASTERIZER_FORCE_BUILTIN_LIBPNG "Force the usage of builting libpng instead of the system version." OFF)
|
||||
|
||||
if(PNG_FOUND AND NOT RASTERIZER_FORCE_BUILTIN_LIBPNG)
|
||||
message(STATUS "Using system libpng.")
|
||||
else()
|
||||
set(ZLIB_LIBRARY "")
|
||||
message(WARNING "Using builtin libpng. This can cause crashes on some platforms.")
|
||||
add_subdirectory(png/zlib)
|
||||
set(ZLIB_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/png/zlib ${CMAKE_CURRENT_BINARY_DIR}/png/zlib)
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
message(STATUS "ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIR}")
|
||||
add_subdirectory(png/libpng)
|
||||
set_target_properties(zlibstatic PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(png_static PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
# target_include_directories(png_static PRIVATE ${ZLIB_INCLUDE_DIR})
|
||||
set(PNG_LIBRARIES png_static zlibstatic)
|
||||
set(PNG_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/png/libpng ${CMAKE_CURRENT_BINARY_DIR}/png/libpng)
|
||||
endif()
|
||||
|
||||
add_subdirectory(libslic3r)
|
||||
add_subdirectory(slic3r)
|
||||
|
||||
# Create a slic3r executable
|
||||
add_executable(slic3r slic3r.cpp)
|
||||
target_link_libraries(slic3r libslic3r libslic3r_gui ${wxWidgets_LIBRARIES} ${CURL_LIBRARIES})
|
||||
# Add the OpenGL and GLU libraries.
|
||||
if (SLIC3R_GUI)
|
||||
if (MSVC)
|
||||
target_link_libraries(slic3r user32.lib Setupapi.lib OpenGL32.Lib GlU32.Lib)
|
||||
elseif (MINGW)
|
||||
target_link_libraries(slic3r -lopengl32)
|
||||
elseif (APPLE)
|
||||
target_link_libraries(slic3r "-framework OpenGL")
|
||||
else ()
|
||||
target_link_libraries(slic3r -lGL -lGLU)
|
||||
endif ()
|
||||
endif ()
|
||||
25
src/Shiny/CMakeLists.txt
Normal file
25
src/Shiny/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
project(Shiny)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
add_library(Shiny STATIC
|
||||
Shiny.h
|
||||
ShinyConfig.h
|
||||
ShinyData.h
|
||||
ShinyMacros.h
|
||||
ShinyManager.c
|
||||
ShinyManager.h
|
||||
ShinyNode.c
|
||||
ShinyNode.h
|
||||
ShinyNodePool.c
|
||||
ShinyNodePool.h
|
||||
ShinyNodeState.c
|
||||
ShinyNodeState.h
|
||||
ShinyOutput.c
|
||||
ShinyOutput.h
|
||||
ShinyPrereqs.h
|
||||
ShinyTools.c
|
||||
ShinyTools.h
|
||||
ShinyVersion.h
|
||||
ShinyZone.c
|
||||
ShinyZone.h
|
||||
)
|
||||
36
src/Shiny/Shiny.h
Normal file
36
src/Shiny/Shiny.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_H
|
||||
#define SHINY_H
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ShinyMacros.h"
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
#include "ShinyManager.h"
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
|
||||
#endif /* SHINY_H */
|
||||
61
src/Shiny/ShinyConfig.h
Normal file
61
src/Shiny/ShinyConfig.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_CONFIG_H
|
||||
#define SHINY_CONFIG_H
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* if SHINY_LOOKUP_RATE is defined to TRUE then Shiny will record the success of its hash function. This is useful for debugging. Default is FALSE.
|
||||
*/
|
||||
#ifndef SHINY_LOOKUP_RATE
|
||||
// #define SHINY_LOOKUP_RATE FALSE
|
||||
#endif
|
||||
|
||||
/* if SHINY_HAS_ENABLED is defined to TRUE then Shiny can be enabled and disabled at runtime. TODO: bla bla...
|
||||
*/
|
||||
#ifndef SHINY_HAS_ENABLED
|
||||
// #define SHINY_HAS_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
/* TODO:
|
||||
*/
|
||||
#define SHINY_OUTPUT_MODE_FLAT 0x1
|
||||
|
||||
/* TODO:
|
||||
*/
|
||||
#define SHINY_OUTPUT_MODE_TREE 0x2
|
||||
|
||||
/* TODO:
|
||||
*/
|
||||
#define SHINY_OUTPUT_MODE_BOTH 0x3
|
||||
|
||||
/* TODO:
|
||||
*/
|
||||
#ifndef SHINY_OUTPUT_MODE
|
||||
#define SHINY_OUTPUT_MODE SHINY_OUTPUT_MODE_BOTH
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_CONFIG_H */
|
||||
102
src/Shiny/ShinyData.h
Normal file
102
src/Shiny/ShinyData.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_DATA_H
|
||||
#define SHINY_DATA_H
|
||||
|
||||
#include "ShinyPrereqs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t entryCount;
|
||||
shinytick_t selfTicks;
|
||||
} ShinyLastData;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
shinytick_t cur;
|
||||
float avg;
|
||||
} ShinyTickData;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cur;
|
||||
float avg;
|
||||
} ShinyCountData;
|
||||
|
||||
typedef struct {
|
||||
ShinyCountData entryCount;
|
||||
ShinyTickData selfTicks;
|
||||
ShinyTickData childTicks;
|
||||
} ShinyData;
|
||||
|
||||
SHINY_INLINE shinytick_t ShinyData_totalTicksCur(const ShinyData *self) {
|
||||
return self->selfTicks.cur + self->childTicks.cur;
|
||||
}
|
||||
|
||||
SHINY_INLINE float ShinyData_totalTicksAvg(const ShinyData *self) {
|
||||
return self->selfTicks.avg + self->childTicks.avg;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyData_computeAverage(ShinyData *self, float a_damping) {
|
||||
self->entryCount.avg = self->entryCount.cur +
|
||||
a_damping * (self->entryCount.avg - self->entryCount.cur);
|
||||
self->selfTicks.avg = self->selfTicks.cur +
|
||||
a_damping * (self->selfTicks.avg - self->selfTicks.cur);
|
||||
self->childTicks.avg = self->childTicks.cur +
|
||||
a_damping * (self->childTicks.avg - self->childTicks.cur);
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyData_copyAverage(ShinyData *self) {
|
||||
self->entryCount.avg = (float) self->entryCount.cur;
|
||||
self->selfTicks.avg = (float) self->selfTicks.cur;
|
||||
self->childTicks.avg = (float) self->childTicks.cur;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyData_clearAll(ShinyData *self) {
|
||||
self->entryCount.cur = 0;
|
||||
self->entryCount.avg = 0;
|
||||
self->selfTicks.cur = 0;
|
||||
self->selfTicks.avg = 0;
|
||||
self->childTicks.cur = 0;
|
||||
self->childTicks.avg = 0;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyData_clearCurrent(ShinyData *self) {
|
||||
self->entryCount.cur = 0;
|
||||
self->selfTicks.cur = 0;
|
||||
self->childTicks.cur = 0;
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_DATA_H */
|
||||
281
src/Shiny/ShinyMacros.h
Normal file
281
src/Shiny/ShinyMacros.h
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_MACROS_H
|
||||
#define SHINY_MACROS_H
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyManager.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_UPDATE() \
|
||||
ShinyManager_update(&Shiny_instance)
|
||||
|
||||
#define PROFILE_SET_DAMPING(floatfrom0to1) \
|
||||
Shiny_instance.damping = (floatfrom0to1);
|
||||
|
||||
#define PROFILE_GET_DAMPING() \
|
||||
(Shiny_instance.damping)
|
||||
|
||||
#define PROFILE_OUTPUT(filename) \
|
||||
ShinyManager_output(&Shiny_instance, (filename))
|
||||
|
||||
#define PROFILE_OUTPUT_STREAM(stream) \
|
||||
ShinyManager_outputToStream(&Shiny_instance, (stream))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define PROFILE_GET_TREE_STRING() \
|
||||
ShinyManager_outputTreeToString(&Shiny_instance)
|
||||
|
||||
#define PROFILE_GET_FLAT_STRING() \
|
||||
ShinyManager_outputFlatToString(&Shiny_instance)
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define PROFILE_DESTROY() \
|
||||
ShinyManager_destroy(&Shiny_instance)
|
||||
|
||||
#define PROFILE_CLEAR() \
|
||||
ShinyManager_clear(&Shiny_instance)
|
||||
|
||||
#define PROFILE_SORT_ZONES() \
|
||||
ShinyManager_sortZones(&Shiny_instance)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_GET_TOTAL_TICKS_CUR() \
|
||||
ShinyData_totalTicksCur(&Shiny_instance.rootZone.data)
|
||||
|
||||
#define PROFILE_GET_TOTAL_TICKS() \
|
||||
ShinyData_totalTicksAvg(&Shiny_instance.rootZone.data)
|
||||
|
||||
#define PROFILE_GET_PROFILED_TICKS_CUR() \
|
||||
(Shiny_instance.rootZone.data.selfTicks.cur)
|
||||
|
||||
#define PROFILE_GET_PROFILED_TICKS() \
|
||||
(Shiny_instance.rootZone.data.selfTicks.avg)
|
||||
|
||||
#define PROFILE_GET_UNPROFILED_TICKS_CUR() \
|
||||
(Shiny_instance.rootZone.data.childTicks.cur)
|
||||
|
||||
#define PROFILE_GET_UNPROFILED_TICKS() \
|
||||
(Shiny_instance.rootZone.data.childTicks.avg)
|
||||
|
||||
#define PROFILE_GET_SHARED_TOTAL_TICKS_CUR(name) \
|
||||
ShinyData_totalTicksCur(&(_PROFILE_ID_ZONE_SHARED(name).data))
|
||||
|
||||
#define PROFILE_GET_SHARED_TOTAL_TICKS(name) \
|
||||
ShinyData_totalTicksAvg(&(_PROFILE_ID_ZONE_SHARED(name).data))
|
||||
|
||||
#define PROFILE_GET_SHARED_SELF_TICKS_CUR(name) \
|
||||
(_PROFILE_ID_ZONE_SHARED(name).data.selfTicks.cur)
|
||||
|
||||
#define PROFILE_GET_SHARED_SELF_TICKS(name) \
|
||||
(_PROFILE_ID_ZONE_SHARED(name).data.selfTicks.avg)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_IS_SHARED_SELF_BELOW(name, floatfrom0to1) \
|
||||
ShinyManager_isZoneSelfTimeBelow( \
|
||||
&Shiny_instance, _PROFILE_ID_ZONE_SHARED(name), floatfrom0to1)
|
||||
|
||||
#define PROFILE_IS_SHARED_TOTAL_BELOW(name, floatfrom0to1) \
|
||||
ShinyManager_isZoneTotalTimeBelow( \
|
||||
&Shiny_instance, _PROFILE_ID_ZONE_SHARED(name), floatfrom0to1)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_END() \
|
||||
ShinyManager_endCurNode(&Shiny_instance)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_BEGIN( name ) \
|
||||
\
|
||||
static _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE(name), #name); \
|
||||
_PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE(name))
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define PROFILE_BLOCK( name ) \
|
||||
\
|
||||
_PROFILE_BLOCK_DEFINE(_PROFILE_ID_BLOCK()); \
|
||||
PROFILE_BEGIN(name)
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define PROFILE_FUNC() \
|
||||
\
|
||||
_PROFILE_BLOCK_DEFINE(_PROFILE_ID_BLOCK()); \
|
||||
static _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE_FUNC(), __FUNCTION__); \
|
||||
_PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_FUNC())
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_CODE( code ) \
|
||||
\
|
||||
do { \
|
||||
static _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE_CODE(), #code); \
|
||||
_PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_CODE()); \
|
||||
{ code; } \
|
||||
PROFILE_END(); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_SHARED_EXTERN( name ) \
|
||||
\
|
||||
_PROFILE_ZONE_DECLARE(extern, _PROFILE_ID_ZONE_SHARED(name))
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_SHARED_DEFINE( name ) \
|
||||
\
|
||||
_PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE_SHARED(name), #name)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#define PROFILE_SHARED_BEGIN( name ) \
|
||||
\
|
||||
_PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_SHARED(name))
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define PROFILE_SHARED_BLOCK( name ) \
|
||||
\
|
||||
_PROFILE_BLOCK_DEFINE(_PROFILE_ID_BLOCK()); \
|
||||
_PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_SHARED(name))
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* public preprocessors */
|
||||
|
||||
#ifdef SHINY_HAS_ENABLED
|
||||
#define PROFILE_SET_ENABLED( boolean ) \
|
||||
Shiny_instance.enabled = boolean
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* internal preprocessors */
|
||||
|
||||
#define _PROFILE_ID_ZONE( name ) __ShinyZone_##name
|
||||
#define _PROFILE_ID_ZONE_FUNC() __ShinyZoneFunc
|
||||
#define _PROFILE_ID_ZONE_CODE() __ShinyZoneCode
|
||||
#define _PROFILE_ID_ZONE_SHARED( name ) name##__ShinyZoneShared
|
||||
#define _PROFILE_ID_BLOCK() __ShinyBlock
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* internal preprocessor */
|
||||
|
||||
#define _PROFILE_ZONE_DEFINE( id, string ) \
|
||||
\
|
||||
ShinyZone id = { \
|
||||
NULL, SHINY_ZONE_STATE_HIDDEN, string, \
|
||||
{ { 0, 0 }, { 0, 0 }, { 0, 0 } } \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* internal preprocessor */
|
||||
|
||||
#define _PROFILE_ZONE_DECLARE( prefix, id ) \
|
||||
\
|
||||
prefix ShinyZone id
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* internal preprocessor */
|
||||
|
||||
#define _PROFILE_BLOCK_DEFINE( id ) \
|
||||
\
|
||||
ShinyEndNodeOnDestruction SHINY_UNUSED id
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* internal preprocessor */
|
||||
|
||||
#define _PROFILE_ZONE_BEGIN( id ) \
|
||||
\
|
||||
do { \
|
||||
static ShinyNodeCache cache = &_ShinyNode_dummy; \
|
||||
ShinyManager_lookupAndBeginNode(&Shiny_instance, &cache, &id); \
|
||||
} while(0)
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#else /* SLIC3R_PROFILE */
|
||||
|
||||
#define PROFILE_UPDATE()
|
||||
#define PROFILE_SET_DAMPING(x)
|
||||
#define PROFILE_GET_DAMPING() 0.0f
|
||||
#define PROFILE_OUTPUT(x)
|
||||
#define PROFILE_OUTPUT_STREAM(x)
|
||||
#define PROFILE_CLEAR()
|
||||
#define PROFILE_GET_TREE_STRING() std::string()
|
||||
#define PROFILE_GET_FLAT_STRING() std::string()
|
||||
#define PROFILE_DESTROY()
|
||||
#define PROFILE_BEGIN(name)
|
||||
#define PROFILE_BLOCK(name)
|
||||
#define PROFILE_FUNC()
|
||||
#define PROFILE_CODE(code) do { code; } while (0)
|
||||
#define PROFILE_SHARED_GLOBAL(name)
|
||||
#define PROFILE_SHARED_MEMBER(name)
|
||||
#define PROFILE_SHARED_DEFINE(name)
|
||||
#define PROFILE_SHARED_BEGIN(name)
|
||||
#define PROFILE_SHARED_BLOCK(name)
|
||||
#define PROFILE_SET_ENABLED(boolean)
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
|
||||
#endif /* SHINY_MACROS_H */
|
||||
445
src/Shiny/ShinyManager.c
Normal file
445
src/Shiny/ShinyManager.c
Normal file
|
|
@ -0,0 +1,445 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyManager.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define TABLE_SIZE_INIT 256
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyManager Shiny_instance = {
|
||||
#if SHINY_HAS_ENABLED == TRUE
|
||||
/* enabled = */ false,
|
||||
#endif
|
||||
/* _lastTick = */ 0,
|
||||
/* _curNode = */ &Shiny_instance.rootNode,
|
||||
/* _tableMask = */ 0,
|
||||
/* _nodeTable = */ _ShinyManager_dummyNodeTable,
|
||||
#if SHINY_LOOKUP_RATE == TRUE
|
||||
/* _lookupCount = */ 0,
|
||||
/* _lookupSuccessCount = */ 0,
|
||||
#endif
|
||||
/* _tableSize = */ 1,
|
||||
/* nodeCount = */ 1,
|
||||
/* zoneCount = */ 1,
|
||||
/* _lastZone = */ &Shiny_instance.rootZone,
|
||||
/* _lastNodePool = */ NULL,
|
||||
/* _firstNodePool = */ NULL,
|
||||
/* rootNode = */ {
|
||||
/* _last = */ { 0, 0 },
|
||||
/* zone = */ &Shiny_instance.rootZone,
|
||||
/* parent = */ &Shiny_instance.rootNode,
|
||||
/* nextSibling = */ NULL,
|
||||
/* firstChild = */ NULL,
|
||||
/* lastChild = */ NULL,
|
||||
/* childCount = */ 0,
|
||||
/* entryLevel = */ 0,
|
||||
/* _cache = */ NULL,
|
||||
/* data = */ { { 0, 0 }, { 0, 0 }, { 0, 0 } }
|
||||
},
|
||||
/* rootZone = */ {
|
||||
/* next = */ NULL,
|
||||
/* _state = */ SHINY_ZONE_STATE_HIDDEN,
|
||||
/* name = */ "<unprofiled>",
|
||||
/* data = */ { { 0, 0 }, { 0, 0 }, { 0, 0 } }
|
||||
},
|
||||
/* damping = */ 0.f, // Damping disabled, every PROFILE_UPDATE will be performed from scratch. Original value: 0.9f
|
||||
/* _initialized = */ FALSE,
|
||||
/* _firstUpdate = */ TRUE
|
||||
};
|
||||
|
||||
ShinyNode* _ShinyManager_dummyNodeTable[] = { NULL };
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4311)
|
||||
#endif
|
||||
|
||||
/* primary hash function */
|
||||
SHINY_INLINE uint32_t hash_value(void* a_pParent, void* a_pZone) {
|
||||
uint32_t a = (uint32_t) a_pParent + (uint32_t) a_pZone;
|
||||
// uint32_t a = *reinterpret_cast<uint32_t*>(&a_pParent) + *reinterpret_cast<uint32_t*>(&a_pZone);
|
||||
|
||||
a = (a+0x7ed55d16) + (a<<12);
|
||||
a = (a^0xc761c23c) ^ (a>>19);
|
||||
return a;
|
||||
}
|
||||
|
||||
/*
|
||||
* secondary hash used as index offset: force it to be odd
|
||||
* so it's relatively prime to the power-of-two table size
|
||||
*/
|
||||
SHINY_INLINE uint32_t hash_offset(uint32_t a) {
|
||||
return ((a << 8) + (a >> 4)) | 1;
|
||||
}
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_preLoad(ShinyManager *self) {
|
||||
if (!self->_initialized) {
|
||||
_ShinyManager_init(self);
|
||||
|
||||
_ShinyManager_createNodeTable(self, TABLE_SIZE_INIT);
|
||||
_ShinyManager_createNodePool(self, TABLE_SIZE_INIT / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_update(ShinyManager *self) {
|
||||
#if SHINY_HAS_ENABLED == TRUE
|
||||
if (!enabled) return;
|
||||
#endif
|
||||
|
||||
_ShinyManager_appendTicksToCurNode(self);
|
||||
ShinyZone_preUpdateChain(&self->rootZone);
|
||||
|
||||
if (self->_firstUpdate || self->damping == 0) {
|
||||
self->_firstUpdate = FALSE;
|
||||
ShinyNode_updateTreeClean(&self->rootNode);
|
||||
ShinyZone_updateChainClean(&self->rootZone);
|
||||
|
||||
} else {
|
||||
ShinyNode_updateTree(&self->rootNode, self->damping);
|
||||
ShinyZone_updateChain(&self->rootZone, self->damping);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_updateClean(ShinyManager *self) {
|
||||
#if SHINY_HAS_ENABLED == TRUE
|
||||
if (!enabled) return;
|
||||
#endif
|
||||
|
||||
_ShinyManager_appendTicksToCurNode(self);
|
||||
ShinyZone_preUpdateChain(&self->rootZone);
|
||||
|
||||
self->_firstUpdate = FALSE;
|
||||
ShinyNode_updateTreeClean(&self->rootNode);
|
||||
ShinyZone_updateChainClean(&self->rootZone);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_clear(ShinyManager *self) {
|
||||
ShinyManager_destroy(self);
|
||||
ShinyManager_preLoad(self);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_destroy(ShinyManager *self) {
|
||||
ShinyManager_destroyNodes(self);
|
||||
ShinyManager_resetZones(self);
|
||||
_ShinyManager_uninit(self);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNode* _ShinyManager_lookupNode(ShinyManager *self, ShinyNodeCache *a_cache, ShinyZone *a_zone) {
|
||||
uint32_t nHash = hash_value(self->_curNode, a_zone);
|
||||
uint32_t nIndex = nHash & self->_tableMask;
|
||||
ShinyNode* pNode = self->_nodeTable[nIndex];
|
||||
|
||||
_ShinyManager_incLookup(self);
|
||||
_ShinyManager_incLookupSuccess(self);
|
||||
|
||||
if (pNode) {
|
||||
uint32_t nStep;
|
||||
|
||||
if (ShinyNode_isEqual(pNode, self->_curNode, a_zone)) return pNode; /* found it! */
|
||||
|
||||
/* hash collision: */
|
||||
|
||||
/* compute a secondary hash function for stepping */
|
||||
nStep = hash_offset(nHash);
|
||||
|
||||
for (;;) {
|
||||
_ShinyManager_incLookup(self);
|
||||
|
||||
nIndex = (nIndex + nStep) & self->_tableMask;
|
||||
pNode = self->_nodeTable[nIndex];
|
||||
|
||||
if (!pNode) break; /* found empty slot */
|
||||
else if (ShinyNode_isEqual(pNode, self->_curNode, a_zone)) return pNode; /* found it! */
|
||||
}
|
||||
|
||||
/* loop is guaranteed to end because the hash table is never full */
|
||||
}
|
||||
|
||||
if (a_zone->_state == SHINY_ZONE_STATE_HIDDEN) { /* zone is not initialized */
|
||||
ShinyZone_init(a_zone, self->_lastZone);
|
||||
|
||||
self->_lastZone = a_zone;
|
||||
self->zoneCount++;
|
||||
|
||||
if (self->_initialized == FALSE) { /* first time init */
|
||||
_ShinyManager_init(self);
|
||||
|
||||
_ShinyManager_createNodeTable(self, TABLE_SIZE_INIT);
|
||||
_ShinyManager_createNodePool(self, TABLE_SIZE_INIT / 2);
|
||||
|
||||
/* initialization has invalidated nIndex
|
||||
* we must compute nIndex again
|
||||
*/
|
||||
return _ShinyManager_createNode(self, a_cache, a_zone);
|
||||
}
|
||||
}
|
||||
|
||||
/* Althouth nodeCount is not updated
|
||||
* it includes rootNode so it adds up.
|
||||
*
|
||||
* check if we need to grow the table
|
||||
* we keep it at most 1/2 full to be very fast
|
||||
*/
|
||||
if (self->_tableSize < 2 * self->nodeCount) {
|
||||
|
||||
_ShinyManager_resizeNodeTable(self, 2 * self->_tableSize);
|
||||
_ShinyManager_resizeNodePool(self, self->nodeCount - 1);
|
||||
|
||||
/* resize has invalidated nIndex
|
||||
* we must compute nIndex again
|
||||
*/
|
||||
return _ShinyManager_createNode(self, a_cache, a_zone);
|
||||
}
|
||||
|
||||
self->nodeCount++;
|
||||
|
||||
{
|
||||
ShinyNode* pNewNode = ShinyNodePool_newItem(self->_lastNodePool);
|
||||
ShinyNode_init(pNewNode, self->_curNode, a_zone, a_cache);
|
||||
|
||||
self->_nodeTable[nIndex] = pNewNode;
|
||||
return pNewNode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void _ShinyManager_insertNode(ShinyManager *self, ShinyNode* a_pNode) {
|
||||
uint32_t nHash = hash_value(a_pNode->parent, a_pNode->zone);
|
||||
uint32_t nIndex = nHash & self->_tableMask;
|
||||
|
||||
if (self->_nodeTable[nIndex]) {
|
||||
uint32_t nStep = hash_offset(nHash);
|
||||
|
||||
while (self->_nodeTable[nIndex])
|
||||
nIndex = (nIndex + nStep) & self->_tableMask;
|
||||
}
|
||||
|
||||
self->_nodeTable[nIndex] = a_pNode;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNode* _ShinyManager_createNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_pZone) {
|
||||
ShinyNode* pNewNode = ShinyNodePool_newItem(self->_lastNodePool);
|
||||
ShinyNode_init(pNewNode, self->_curNode, a_pZone, a_cache);
|
||||
|
||||
self->nodeCount++;
|
||||
_ShinyManager_insertNode(self, pNewNode);
|
||||
return pNewNode;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void _ShinyManager_createNodePool(ShinyManager *self, uint32_t a_nCount) {
|
||||
self->_firstNodePool = ShinyNodePool_create(a_nCount);
|
||||
self->_lastNodePool = self->_firstNodePool;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void _ShinyManager_resizeNodePool(ShinyManager *self, uint32_t a_nCount) {
|
||||
ShinyNodePool* pPool = ShinyNodePool_create(a_nCount);
|
||||
self->_lastNodePool->nextPool = pPool;
|
||||
self->_lastNodePool = pPool;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void _ShinyManager_createNodeTable(ShinyManager *self, uint32_t a_nCount) {
|
||||
self->_tableSize = a_nCount;
|
||||
self->_tableMask = a_nCount - 1;
|
||||
|
||||
self->_nodeTable = (ShinyNodeTable*)
|
||||
malloc(sizeof(ShinyNode) * a_nCount);
|
||||
|
||||
memset(self->_nodeTable, 0, a_nCount * sizeof(ShinyNode*));
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void _ShinyManager_resizeNodeTable(ShinyManager *self, uint32_t a_nCount) {
|
||||
ShinyNodePool* pPool;
|
||||
|
||||
free(self->_nodeTable);
|
||||
_ShinyManager_createNodeTable(self, a_nCount);
|
||||
|
||||
pPool = self->_firstNodePool;
|
||||
while (pPool) {
|
||||
|
||||
ShinyNode *pIter = ShinyNodePool_firstItem(pPool);
|
||||
|
||||
while (pIter != pPool->_nextItem)
|
||||
_ShinyManager_insertNode(self, pIter++);
|
||||
|
||||
pPool = pPool->nextPool;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_resetZones(ShinyManager *self) {
|
||||
ShinyZone_resetChain(&self->rootZone);
|
||||
self->_lastZone = &self->rootZone;
|
||||
self->zoneCount = 1;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_destroyNodes(ShinyManager *self) {
|
||||
if (self->_firstNodePool) {
|
||||
ShinyNodePool_destroy(self->_firstNodePool);
|
||||
self->_firstNodePool = NULL;
|
||||
}
|
||||
|
||||
if (self->_nodeTable != _ShinyManager_dummyNodeTable) {
|
||||
free(self->_nodeTable);
|
||||
|
||||
self->_nodeTable = _ShinyManager_dummyNodeTable;
|
||||
self->_tableSize = 1;
|
||||
self->_tableMask = 0;
|
||||
}
|
||||
|
||||
self->_curNode = &self->rootNode;
|
||||
self->nodeCount = 1;
|
||||
|
||||
_ShinyManager_init(self);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
const char* ShinyManager_getOutputErrorString(ShinyManager *self) {
|
||||
if (self->_firstUpdate) return "!!! Profile data must first be updated !!!";
|
||||
else if (!self->_initialized) return "!!! No profiles where executed !!!";
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4996)
|
||||
#endif
|
||||
|
||||
int ShinyManager_output(ShinyManager *self, const char *a_filename) {
|
||||
if (!a_filename) {
|
||||
ShinyManager_outputToStream(self, stdout);
|
||||
|
||||
} else {
|
||||
FILE *file = fopen(a_filename, "w");
|
||||
if (!file) return FALSE;
|
||||
ShinyManager_outputToStream(self, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyManager_outputToStream(ShinyManager *self, FILE *a_stream) {
|
||||
const char *error = ShinyManager_getOutputErrorString(self);
|
||||
|
||||
if (error) {
|
||||
fwrite(error, 1, strlen(error), a_stream);
|
||||
fwrite("\n\n", 1, 2, a_stream);
|
||||
return;
|
||||
}
|
||||
|
||||
#if SHINY_OUTPUT_MODE & SHINY_OUTPUT_MODE_FLAT
|
||||
ShinyManager_sortZones(self);
|
||||
|
||||
{
|
||||
int size = ShinyPrintZonesSize(self->zoneCount);
|
||||
char *buffer = (char*) malloc(size);
|
||||
ShinyPrintZones(buffer, &self->rootZone);
|
||||
fwrite(buffer, 1, size - 1, a_stream);
|
||||
fwrite("\n\n", 1, 2, a_stream);
|
||||
free(buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SHINY_OUTPUT_MODE & SHINY_OUTPUT_MODE_TREE
|
||||
{
|
||||
int size = ShinyPrintNodesSize(self->nodeCount);
|
||||
char *buffer = (char*) malloc(size);
|
||||
ShinyPrintNodes(buffer, &self->rootNode);
|
||||
fwrite(buffer, 1, size - 1, a_stream);
|
||||
fwrite("\n\n", 1, 2, a_stream);
|
||||
free(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
263
src/Shiny/ShinyManager.h
Normal file
263
src/Shiny/ShinyManager.h
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_MANAGER_H
|
||||
#define SHINY_MANAGER_H
|
||||
|
||||
#include "ShinyZone.h"
|
||||
#include "ShinyNode.h"
|
||||
#include "ShinyNodePool.h"
|
||||
#include "ShinyTools.h"
|
||||
#include "ShinyOutput.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
#ifdef SHINY_HAS_ENABLED
|
||||
bool enabled;
|
||||
#endif
|
||||
|
||||
shinytick_t _lastTick;
|
||||
|
||||
ShinyNode* _curNode;
|
||||
|
||||
uint32_t _tableMask; /* = _tableSize - 1 */
|
||||
|
||||
ShinyNodeTable* _nodeTable;
|
||||
|
||||
#ifdef SHINY_LOOKUP_RATE
|
||||
uint64_t _lookupCount;
|
||||
uint64_t _lookupSuccessCount;
|
||||
#endif
|
||||
|
||||
uint32_t _tableSize;
|
||||
|
||||
uint32_t nodeCount;
|
||||
uint32_t zoneCount;
|
||||
|
||||
ShinyZone* _lastZone;
|
||||
|
||||
ShinyNodePool* _lastNodePool;
|
||||
ShinyNodePool* _firstNodePool;
|
||||
|
||||
ShinyNode rootNode;
|
||||
ShinyZone rootZone;
|
||||
|
||||
float damping;
|
||||
|
||||
int _initialized;
|
||||
int _firstUpdate;
|
||||
} ShinyManager;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
extern ShinyNode* _ShinyManager_dummyNodeTable[];
|
||||
|
||||
extern ShinyManager Shiny_instance;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE void _ShinyManager_appendTicksToCurNode(ShinyManager *self) {
|
||||
shinytick_t curTick;
|
||||
ShinyGetTicks(&curTick);
|
||||
|
||||
ShinyNode_appendTicks(self->_curNode, curTick - self->_lastTick);
|
||||
self->_lastTick = curTick;
|
||||
}
|
||||
|
||||
SHINY_API ShinyNode* _ShinyManager_lookupNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_zone);
|
||||
|
||||
SHINY_API void _ShinyManager_createNodeTable(ShinyManager *self, uint32_t a_count);
|
||||
SHINY_API void _ShinyManager_resizeNodeTable(ShinyManager *self, uint32_t a_count);
|
||||
|
||||
SHINY_API void _ShinyManager_createNodePool(ShinyManager *self, uint32_t a_count);
|
||||
SHINY_API void _ShinyManager_resizeNodePool(ShinyManager *self, uint32_t a_count);
|
||||
|
||||
SHINY_API ShinyNode* _ShinyManager_createNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_pZone);
|
||||
SHINY_API void _ShinyManager_insertNode(ShinyManager *self, ShinyNode* a_pNode);
|
||||
|
||||
SHINY_INLINE void _ShinyManager_init(ShinyManager *self) {
|
||||
self->_initialized = TRUE;
|
||||
|
||||
self->rootNode._last.entryCount = 1;
|
||||
self->rootNode._last.selfTicks = 0;
|
||||
ShinyGetTicks(&self->_lastTick);
|
||||
}
|
||||
|
||||
SHINY_INLINE void _ShinyManager_uninit(ShinyManager *self) {
|
||||
self->_initialized = FALSE;
|
||||
|
||||
ShinyNode_clear(&self->rootNode);
|
||||
self->rootNode.parent = &self->rootNode;
|
||||
self->rootNode.zone = &self->rootZone;
|
||||
}
|
||||
|
||||
#ifdef SHINY_LOOKUP_RATE
|
||||
SHINY_INLINE void _ShinyManager_incLookup(ShinyManager *self) { self->_lookupCount++; }
|
||||
SHINY_INLINE void _ShinyManager_incLookupSuccess(ShinyManager *self) { self->_lookupSuccessCount++; }
|
||||
SHINY_INLINE float ShinyManager_lookupRate(const ShinyManager *self) { return ((float) self->_lookupSuccessCount) / ((float) self->_lookupCount); }
|
||||
|
||||
#else
|
||||
SHINY_INLINE void _ShinyManager_incLookup(ShinyManager * self) { self = self; }
|
||||
SHINY_INLINE void _ShinyManager_incLookupSuccess(ShinyManager * self) { self = self; }
|
||||
SHINY_INLINE float ShinyManager_lookupRate(const ShinyManager * self) { self = self; return -1; }
|
||||
#endif
|
||||
|
||||
SHINY_API void ShinyManager_resetZones(ShinyManager *self);
|
||||
SHINY_API void ShinyManager_destroyNodes(ShinyManager *self);
|
||||
|
||||
SHINY_INLINE float ShinyManager_tableUsage(const ShinyManager *self) {
|
||||
return ((float) self->nodeCount) / ((float) self->_tableSize);
|
||||
}
|
||||
|
||||
SHINY_INLINE uint32_t ShinyManager_allocMemInBytes(const ShinyManager *self) {
|
||||
return self->_tableSize * sizeof(ShinyNode*)
|
||||
+ (self->_firstNodePool)? ShinyNodePool_memoryUsageChain(self->_firstNodePool) : 0;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyManager_beginNode(ShinyManager *self, ShinyNode* a_node) {
|
||||
ShinyNode_beginEntry(a_node);
|
||||
|
||||
_ShinyManager_appendTicksToCurNode(self);
|
||||
self->_curNode = a_node;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyManager_lookupAndBeginNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_zone) {
|
||||
#ifdef SHINY_HAS_ENABLED
|
||||
if (!self->enabled) return;
|
||||
#endif
|
||||
|
||||
if (self->_curNode != (*a_cache)->parent)
|
||||
*a_cache = _ShinyManager_lookupNode(self, a_cache, a_zone);
|
||||
|
||||
ShinyManager_beginNode(self, *a_cache);
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyManager_endCurNode(ShinyManager *self) {
|
||||
#ifdef SHINY_HAS_ENABLED
|
||||
if (!self->enabled) return;
|
||||
#endif
|
||||
|
||||
_ShinyManager_appendTicksToCurNode(self);
|
||||
self->_curNode = self->_curNode->parent;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
SHINY_API void ShinyManager_preLoad(ShinyManager *self);
|
||||
|
||||
SHINY_API void ShinyManager_updateClean(ShinyManager *self);
|
||||
SHINY_API void ShinyManager_update(ShinyManager *self);
|
||||
|
||||
SHINY_API void ShinyManager_clear(ShinyManager *self);
|
||||
SHINY_API void ShinyManager_destroy(ShinyManager *self);
|
||||
|
||||
SHINY_INLINE void ShinyManager_sortZones(ShinyManager *self) {
|
||||
if (self->rootZone.next)
|
||||
self->_lastZone = ShinyZone_sortChain(&self->rootZone.next);
|
||||
}
|
||||
|
||||
SHINY_API const char* ShinyManager_getOutputErrorString(ShinyManager *self);
|
||||
|
||||
SHINY_API int ShinyManager_output(ShinyManager *self, const char *a_filename);
|
||||
SHINY_API void ShinyManager_outputToStream(ShinyManager *self, FILE *stream);
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
||||
SHINY_INLINE std::string ShinyManager_outputTreeToString(ShinyManager *self) {
|
||||
const char* error = ShinyManager_getOutputErrorString(self);
|
||||
if (error) return error;
|
||||
else return ShinyNodesToString(&self->rootNode, self->nodeCount);
|
||||
}
|
||||
|
||||
SHINY_INLINE std::string ShinyManager_outputFlatToString(ShinyManager *self) {
|
||||
const char* error = ShinyManager_getOutputErrorString(self);
|
||||
if (error) return error;
|
||||
|
||||
ShinyManager_sortZones(self);
|
||||
return ShinyZonesToString(&self->rootZone, self->zoneCount);
|
||||
}
|
||||
|
||||
extern "C" { /* end of c++ */
|
||||
#endif
|
||||
|
||||
SHINY_INLINE int ShinyManager_isZoneSelfTimeBelow(ShinyManager *self, ShinyZone* a_zone, float a_percentage) {
|
||||
return a_percentage * (float) self->rootZone.data.childTicks.cur
|
||||
<= (float) a_zone->data.selfTicks.cur;
|
||||
}
|
||||
|
||||
SHINY_INLINE int ShinyManager_isZoneTotalTimeBelow(ShinyManager *self, ShinyZone* a_zone, float a_percentage) {
|
||||
return a_percentage * (float) self->rootZone.data.childTicks.cur
|
||||
<= (float) ShinyData_totalTicksCur(&a_zone->data);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
SHINY_INLINE void ShinyManager_enumerateNodes(ShinyManager *self, void (*a_func)(const ShinyNode*)) {
|
||||
ShinyNode_enumerateNodes(&self->rootNode, a_func);
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyManager_enumerateZones(ShinyManager *self, void (*a_func)(const ShinyZone*)) {
|
||||
ShinyZone_enumerateZones(&self->rootZone, a_func);
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
||||
template <class T> void ShinyManager_enumerateNodes(ShinyManager *self, T* a_this, void (T::*a_func)(const ShinyNode*)) {
|
||||
ShinyNode_enumerateNodes(&self->rootNode, a_this, a_func);
|
||||
}
|
||||
|
||||
template <class T> void ShinyManager_enumerateZones(ShinyManager *self, T* a_this, void (T::*a_func)(const ShinyZone*)) {
|
||||
ShinyZone_enumerateZones(&self->rootZone, a_this, a_func);
|
||||
}
|
||||
|
||||
extern "C" { /* end of c++ */
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
||||
class ShinyEndNodeOnDestruction {
|
||||
public:
|
||||
|
||||
SHINY_INLINE ~ShinyEndNodeOnDestruction() {
|
||||
ShinyManager_endCurNode(&Shiny_instance);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_MANAGER_H */
|
||||
129
src/Shiny/ShinyNode.c
Normal file
129
src/Shiny/ShinyNode.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyNode.h"
|
||||
#include "ShinyZone.h"
|
||||
#include "ShinyNodeState.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNode _ShinyNode_dummy = {
|
||||
/* _last = */ { 0, 0 },
|
||||
/* zone = */ NULL,
|
||||
/* parent = */ NULL,
|
||||
/* nextSibling = */ NULL,
|
||||
/* firstChild = */ NULL,
|
||||
/* lastChild = */ NULL
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyNode_updateTree(ShinyNode* first, float a_damping) {
|
||||
ShinyNodeState *top = NULL;
|
||||
ShinyNode *node = first;
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
top = ShinyNodeState_push(top, node);
|
||||
node = node->firstChild;
|
||||
} while (node);
|
||||
|
||||
for (;;) {
|
||||
node = ShinyNodeState_finishAndGetNext(top, a_damping);
|
||||
top = ShinyNodeState_pop(top);
|
||||
|
||||
if (node) break;
|
||||
else if (!top) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyNode_updateTreeClean(ShinyNode* first) {
|
||||
ShinyNodeState *top = NULL;
|
||||
ShinyNode *node = first;
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
top = ShinyNodeState_push(top, node);
|
||||
node = node->firstChild;
|
||||
} while (node);
|
||||
|
||||
for (;;) {
|
||||
node = ShinyNodeState_finishAndGetNextClean(top);
|
||||
top = ShinyNodeState_pop(top);
|
||||
|
||||
if (node) break;
|
||||
else if (!top) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
const ShinyNode* ShinyNode_findNextInTree(const ShinyNode* self) {
|
||||
if (self->firstChild) {
|
||||
return self->firstChild;
|
||||
|
||||
} else if (self->nextSibling) {
|
||||
return self->nextSibling;
|
||||
|
||||
} else {
|
||||
ShinyNode* pParent = self->parent;
|
||||
|
||||
while (!ShinyNode_isRoot(pParent)) {
|
||||
if (pParent->nextSibling) return pParent->nextSibling;
|
||||
else pParent = pParent->parent;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyNode_clear(ShinyNode* self) {
|
||||
memset(self, 0, sizeof(ShinyNode));
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyNode_enumerateNodes(const ShinyNode* a_node, void (*a_func)(const ShinyNode*)) {
|
||||
a_func(a_node);
|
||||
|
||||
if (a_node->firstChild) ShinyNode_enumerateNodes(a_node->firstChild, a_func);
|
||||
if (a_node->nextSibling) ShinyNode_enumerateNodes(a_node->nextSibling, a_func);
|
||||
}
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
133
src/Shiny/ShinyNode.h
Normal file
133
src/Shiny/ShinyNode.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_NODE_H
|
||||
#define SHINY_NODE_H
|
||||
|
||||
#include "ShinyData.h"
|
||||
#include "ShinyTools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct _ShinyNode {
|
||||
|
||||
ShinyLastData _last;
|
||||
|
||||
struct _ShinyZone* zone;
|
||||
struct _ShinyNode* parent;
|
||||
struct _ShinyNode* nextSibling;
|
||||
|
||||
struct _ShinyNode* firstChild;
|
||||
struct _ShinyNode* lastChild;
|
||||
|
||||
uint32_t childCount;
|
||||
uint32_t entryLevel;
|
||||
|
||||
ShinyNodeCache* _cache;
|
||||
|
||||
ShinyData data;
|
||||
|
||||
} ShinyNode;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
extern ShinyNode _ShinyNode_dummy;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE void ShinyNode_addChild(ShinyNode* self, ShinyNode* a_child) {
|
||||
if (self->childCount++) {
|
||||
self->lastChild->nextSibling = a_child;
|
||||
self->lastChild = a_child;
|
||||
|
||||
} else {
|
||||
self->lastChild = a_child;
|
||||
self->firstChild = a_child;
|
||||
}
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyNode_init(ShinyNode* self, ShinyNode* a_parent, struct _ShinyZone* a_zone, ShinyNodeCache* a_cache) {
|
||||
/* NOTE: all member variables are assumed to be zero when allocated */
|
||||
|
||||
self->zone = a_zone;
|
||||
self->parent = a_parent;
|
||||
|
||||
self->entryLevel = a_parent->entryLevel + 1;
|
||||
ShinyNode_addChild(a_parent, self);
|
||||
|
||||
self->_cache = a_cache;
|
||||
}
|
||||
|
||||
SHINY_API void ShinyNode_updateTree(ShinyNode* self, float a_damping);
|
||||
SHINY_API void ShinyNode_updateTreeClean(ShinyNode* self);
|
||||
|
||||
SHINY_INLINE void ShinyNode_destroy(ShinyNode* self) {
|
||||
*(self->_cache) = &_ShinyNode_dummy;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyNode_appendTicks(ShinyNode* self, shinytick_t a_elapsedTicks) {
|
||||
self->_last.selfTicks += a_elapsedTicks;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyNode_beginEntry(ShinyNode* self) {
|
||||
self->_last.entryCount++;
|
||||
}
|
||||
|
||||
SHINY_INLINE int ShinyNode_isRoot(ShinyNode* self) {
|
||||
return (self->entryLevel == 0);
|
||||
}
|
||||
|
||||
SHINY_INLINE int ShinyNode_isDummy(ShinyNode* self) {
|
||||
return (self == &_ShinyNode_dummy);
|
||||
}
|
||||
|
||||
SHINY_INLINE int ShinyNode_isEqual(ShinyNode* self, const ShinyNode* a_parent, const struct _ShinyZone* a_zone) {
|
||||
return (self->parent == a_parent && self->zone == a_zone);
|
||||
}
|
||||
|
||||
SHINY_API const ShinyNode* ShinyNode_findNextInTree(const ShinyNode* self);
|
||||
|
||||
SHINY_API void ShinyNode_clear(ShinyNode* self);
|
||||
|
||||
SHINY_API void ShinyNode_enumerateNodes(const ShinyNode* a_node, void (*a_func)(const ShinyNode*));
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
||||
template <class T>
|
||||
void ShinyNode_enumerateNodes(const ShinyNode* a_node, T* a_this, void (T::*a_func)(const ShinyNode*)) {
|
||||
(a_this->*a_func)(a_node);
|
||||
|
||||
if (a_node->firstChild) ShinyNode_enumerateNodes(a_node->firstChild, a_this, a_func);
|
||||
if (a_node->nextSibling) ShinyNode_enumerateNodes(a_node->nextSibling, a_this, a_func);
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* SHINY_NODE_H */
|
||||
77
src/Shiny/ShinyNodePool.c
Normal file
77
src/Shiny/ShinyNodePool.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyNodePool.h"
|
||||
#include "ShinyTools.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNodePool* ShinyNodePool_create(uint32_t a_items) {
|
||||
ShinyNodePool* pPool = (ShinyNodePool*)
|
||||
malloc(sizeof(ShinyNodePool) + sizeof(ShinyNode) * (a_items - 1));
|
||||
|
||||
pPool->nextPool = NULL;
|
||||
pPool->_nextItem = &pPool->_items[0];
|
||||
pPool->endOfItems = &pPool->_items[a_items];
|
||||
|
||||
memset(&pPool->_items[0], 0, a_items * sizeof(ShinyNode));
|
||||
return pPool;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
uint32_t ShinyNodePool_memoryUsageChain(ShinyNodePool *first) {
|
||||
uint32_t bytes = (uint32_t) ((char*) first->endOfItems - (char*) first);
|
||||
ShinyNodePool *pool = first->nextPool;
|
||||
|
||||
while (pool) {
|
||||
bytes += (uint32_t) ((char*) pool->endOfItems - (char*) pool);
|
||||
pool = pool->nextPool;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyNodePool_destroy(ShinyNodePool *self) {
|
||||
ShinyNode* firstNode = ShinyNodePool_firstItem(self);
|
||||
ShinyNode* lastNode = self->_nextItem;
|
||||
|
||||
while (firstNode != lastNode)
|
||||
ShinyNode_destroy(firstNode++);
|
||||
|
||||
/* TODO: make this into a loop or a tail recursion */
|
||||
if (self->nextPool) ShinyNodePool_destroy(self->nextPool);
|
||||
free(self);
|
||||
}
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
67
src/Shiny/ShinyNodePool.h
Normal file
67
src/Shiny/ShinyNodePool.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_NODE_POOL_H
|
||||
#define SHINY_NODE_POOL_H
|
||||
|
||||
#include "ShinyNode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct _ShinyNodePool {
|
||||
|
||||
struct _ShinyNodePool* nextPool;
|
||||
|
||||
ShinyNode *_nextItem;
|
||||
ShinyNode *endOfItems;
|
||||
|
||||
ShinyNode _items[1];
|
||||
|
||||
} ShinyNodePool;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE ShinyNode* ShinyNodePool_firstItem(ShinyNodePool *self) {
|
||||
return &(self->_items[0]);
|
||||
}
|
||||
|
||||
SHINY_INLINE ShinyNode* ShinyNodePool_newItem(ShinyNodePool *self) {
|
||||
return self->_nextItem++;
|
||||
}
|
||||
|
||||
ShinyNodePool* ShinyNodePool_create(uint32_t a_items);
|
||||
void ShinyNodePool_destroy(ShinyNodePool *self);
|
||||
|
||||
uint32_t ShinyNodePool_memoryUsageChain(ShinyNodePool *first);
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_NODE_POOL_H */
|
||||
108
src/Shiny/ShinyNodeState.c
Normal file
108
src/Shiny/ShinyNodeState.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyNodeState.h"
|
||||
#include "ShinyNode.h"
|
||||
#include "ShinyZone.h"
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNodeState* ShinyNodeState_push(ShinyNodeState *a_top, ShinyNode *a_node) {
|
||||
ShinyZone *zone = a_node->zone;
|
||||
ShinyNodeState *self = (ShinyNodeState*) malloc(sizeof(ShinyNodeState));
|
||||
self->node = a_node;
|
||||
self->_prev = a_top;
|
||||
|
||||
a_node->data.selfTicks.cur = a_node->_last.selfTicks;
|
||||
a_node->data.entryCount.cur = a_node->_last.entryCount;
|
||||
|
||||
zone->data.selfTicks.cur += a_node->_last.selfTicks;
|
||||
zone->data.entryCount.cur += a_node->_last.entryCount;
|
||||
|
||||
a_node->data.childTicks.cur = 0;
|
||||
a_node->_last.selfTicks = 0;
|
||||
a_node->_last.entryCount = 0;
|
||||
|
||||
self->zoneUpdating = zone->_state != SHINY_ZONE_STATE_UPDATING;
|
||||
if (self->zoneUpdating) {
|
||||
zone->_state = SHINY_ZONE_STATE_UPDATING;
|
||||
} else {
|
||||
zone->data.childTicks.cur -= a_node->data.selfTicks.cur;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNodeState* ShinyNodeState_pop(ShinyNodeState *a_top) {
|
||||
ShinyNodeState *prev = a_top->_prev;
|
||||
free(a_top);
|
||||
return prev;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNode* ShinyNodeState_finishAndGetNext(ShinyNodeState *self, float a_damping) {
|
||||
ShinyNode *node = self->node;
|
||||
ShinyZone *zone = node->zone;
|
||||
|
||||
if (self->zoneUpdating) {
|
||||
zone->data.childTicks.cur += node->data.childTicks.cur;
|
||||
zone->_state = SHINY_ZONE_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
ShinyData_computeAverage(&node->data, a_damping);
|
||||
|
||||
if (!ShinyNode_isRoot(node))
|
||||
node->parent->data.childTicks.cur += node->data.selfTicks.cur + node->data.childTicks.cur;
|
||||
|
||||
return node->nextSibling;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNode* ShinyNodeState_finishAndGetNextClean(ShinyNodeState *self) {
|
||||
ShinyNode *node = self->node;
|
||||
ShinyZone *zone = node->zone;
|
||||
|
||||
if (self->zoneUpdating) {
|
||||
zone->data.childTicks.cur += node->data.childTicks.cur;
|
||||
zone->_state = SHINY_ZONE_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
ShinyData_copyAverage(&node->data);
|
||||
|
||||
if (!ShinyNode_isRoot(node))
|
||||
node->parent->data.childTicks.cur += node->data.selfTicks.cur + node->data.childTicks.cur;
|
||||
|
||||
return node->nextSibling;
|
||||
}
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
56
src/Shiny/ShinyNodeState.h
Normal file
56
src/Shiny/ShinyNodeState.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_NODE_STATE_H
|
||||
#define SHINY_NODE_STATE_H
|
||||
|
||||
#include "ShinyNode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct _ShinyNodeState {
|
||||
ShinyNode *node;
|
||||
int zoneUpdating;
|
||||
|
||||
struct _ShinyNodeState *_prev;
|
||||
} ShinyNodeState;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
ShinyNodeState* ShinyNodeState_push(ShinyNodeState *a_top, ShinyNode *a_node);
|
||||
ShinyNodeState* ShinyNodeState_pop(ShinyNodeState *a_top);
|
||||
|
||||
ShinyNode* ShinyNodeState_finishAndGetNext(ShinyNodeState *self, float a_damping);
|
||||
ShinyNode* ShinyNodeState_finishAndGetNextClean(ShinyNodeState *self);
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_NODE_STATE_H */
|
||||
189
src/Shiny/ShinyOutput.c
Normal file
189
src/Shiny/ShinyOutput.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyOutput.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
# pragma warning(disable: 4996)
|
||||
# define snprintf _snprintf
|
||||
# define TRAILING 0
|
||||
|
||||
#else
|
||||
# define TRAILING 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define OUTPUT_WIDTH_CALL 6
|
||||
#define OUTPUT_WIDTH_TIME 6
|
||||
#define OUTPUT_WIDTH_PERC 4
|
||||
#define OUTPUT_WIDTH_SUM 120
|
||||
|
||||
#define OUTPUT_WIDTH_DATA (1+OUTPUT_WIDTH_CALL + 1 + 2*(OUTPUT_WIDTH_TIME+4+OUTPUT_WIDTH_PERC+1) + 1)
|
||||
#define OUTPUT_WIDTH_NAME (OUTPUT_WIDTH_SUM - OUTPUT_WIDTH_DATA)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE char* printHeader(char *output, const char *a_title) {
|
||||
snprintf(output, OUTPUT_WIDTH_SUM + TRAILING,
|
||||
"%-*s %*s %*s %*s",
|
||||
OUTPUT_WIDTH_NAME, a_title,
|
||||
OUTPUT_WIDTH_CALL, "calls",
|
||||
OUTPUT_WIDTH_TIME+4+OUTPUT_WIDTH_PERC+1, "self time",
|
||||
OUTPUT_WIDTH_TIME+4+OUTPUT_WIDTH_PERC+1, "total time");
|
||||
|
||||
return output + OUTPUT_WIDTH_SUM;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE char* printData(char *output, const ShinyData *a_data, float a_topercent) {
|
||||
float totalTicksAvg = ShinyData_totalTicksAvg(a_data);
|
||||
const ShinyTimeUnit *selfUnit = ShinyGetTimeUnit(a_data->selfTicks.avg);
|
||||
const ShinyTimeUnit *totalUnit = ShinyGetTimeUnit(totalTicksAvg);
|
||||
|
||||
snprintf(output, OUTPUT_WIDTH_DATA + TRAILING,
|
||||
" %*.1f %*.0f %-2s %*.0f%% %*.0f %-2s %*.0f%%",
|
||||
OUTPUT_WIDTH_CALL, a_data->entryCount.avg,
|
||||
OUTPUT_WIDTH_TIME, a_data->selfTicks.avg * selfUnit->invTickFreq, selfUnit->suffix,
|
||||
OUTPUT_WIDTH_PERC, a_data->selfTicks.avg * a_topercent,
|
||||
OUTPUT_WIDTH_TIME, totalTicksAvg * totalUnit->invTickFreq, totalUnit->suffix,
|
||||
OUTPUT_WIDTH_PERC, totalTicksAvg * a_topercent);
|
||||
|
||||
return output + OUTPUT_WIDTH_DATA;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE char* printNode(char* output, const ShinyNode *a_node, float a_topercent) {
|
||||
int offset = a_node->entryLevel * 2;
|
||||
|
||||
snprintf(output, OUTPUT_WIDTH_NAME + TRAILING, "%*s%-*s",
|
||||
offset, "", OUTPUT_WIDTH_NAME - offset, a_node->zone->name);
|
||||
|
||||
output += OUTPUT_WIDTH_NAME;
|
||||
|
||||
output = printData(output, &a_node->data, a_topercent);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE char* printZone(char* output, const ShinyZone *a_zone, float a_topercent) {
|
||||
snprintf(output, OUTPUT_WIDTH_NAME + TRAILING, "%-*s",
|
||||
OUTPUT_WIDTH_NAME, a_zone->name);
|
||||
|
||||
output += OUTPUT_WIDTH_NAME;
|
||||
|
||||
output = printData(output, &a_zone->data, a_topercent);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
int ShinyPrintNodesSize(uint32_t a_count) {
|
||||
return (1 + a_count) * (OUTPUT_WIDTH_SUM + 1);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
int ShinyPrintZonesSize(uint32_t a_count) {
|
||||
return (1 + a_count) * (OUTPUT_WIDTH_SUM + 1);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyPrintANode(char* output, const ShinyNode *a_node, const ShinyNode *a_root) {
|
||||
float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
|
||||
output = printNode(output, a_node, fTicksToPc);
|
||||
(*output++) = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyPrintAZone(char* output, const ShinyZone *a_zone, const ShinyZone *a_root) {
|
||||
float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
|
||||
output = printZone(output, a_zone, fTicksToPc);
|
||||
(*output++) = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyPrintNodes(char* output, const ShinyNode *a_root) {
|
||||
float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
|
||||
const ShinyNode *node = a_root;
|
||||
|
||||
output = printHeader(output, "call tree");
|
||||
(*output++) = '\n';
|
||||
|
||||
for (;;) {
|
||||
output = printNode(output, node, fTicksToPc);
|
||||
|
||||
node = ShinyNode_findNextInTree(node);
|
||||
if (node) {
|
||||
(*output++) = '\n';
|
||||
} else {
|
||||
(*output++) = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyPrintZones(char* output, const ShinyZone *a_root) {
|
||||
float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
|
||||
const ShinyZone *zone = a_root;
|
||||
|
||||
output = printHeader(output, "sorted list");
|
||||
(*output++) = '\n';
|
||||
|
||||
for (;;) {
|
||||
output = printZone(output, zone, fTicksToPc);
|
||||
|
||||
zone = zone->next;
|
||||
if (zone) {
|
||||
(*output++) = '\n';
|
||||
} else {
|
||||
(*output++) = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
68
src/Shiny/ShinyOutput.h
Normal file
68
src/Shiny/ShinyOutput.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_OUTPUT_H
|
||||
#define SHINY_OUTPUT_H
|
||||
|
||||
#include "ShinyNode.h"
|
||||
#include "ShinyZone.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_API int ShinyPrintNodesSize(uint32_t a_count);
|
||||
SHINY_API int ShinyPrintZonesSize(uint32_t a_count);
|
||||
|
||||
SHINY_API void ShinyPrintANode(char* output, const ShinyNode *a_node, const ShinyNode *a_root);
|
||||
SHINY_API void ShinyPrintAZone(char* output, const ShinyZone *a_zone, const ShinyZone *a_root);
|
||||
|
||||
SHINY_API void ShinyPrintNodes(char* output, const ShinyNode *a_root);
|
||||
SHINY_API void ShinyPrintZones(char* output, const ShinyZone *a_root);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#include <string>
|
||||
|
||||
SHINY_INLINE std::string ShinyNodesToString(const ShinyNode *a_root, uint32_t a_count) {
|
||||
std::string str;
|
||||
str.resize(ShinyPrintNodesSize(a_count) - 1);
|
||||
ShinyPrintNodes(&str[0], a_root);
|
||||
return str;
|
||||
}
|
||||
|
||||
SHINY_INLINE std::string ShinyZonesToString(const ShinyZone *a_root, uint32_t a_count) {
|
||||
std::string str;
|
||||
str.resize(ShinyPrintZonesSize(a_count) - 1);
|
||||
ShinyPrintZones(&str[0], a_root);
|
||||
return str;
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* SHINY_OUTPUT_H */
|
||||
138
src/Shiny/ShinyPrereqs.h
Normal file
138
src/Shiny/ShinyPrereqs.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_PREREQS_H
|
||||
#define SHINY_PREREQS_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0x0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 0x1
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#include "ShinyConfig.h"
|
||||
#include "ShinyVersion.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define SHINY_PLATFORM_WIN32 0x1
|
||||
#define SHINY_PLATFORM_POSIX 0x2
|
||||
|
||||
#if defined (_WIN32)
|
||||
# define SHINY_PLATFORM SHINY_PLATFORM_WIN32
|
||||
|
||||
#else /* ASSUME: POSIX-compliant OS */
|
||||
# define SHINY_PLATFORM SHINY_PLATFORM_POSIX
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define SHINY_COMPILER_MSVC 0x1
|
||||
#define SHINY_COMPILER_GNUC 0x2
|
||||
#define SHINY_COMPILER_OTHER 0x3
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
# define SHINY_COMPILER SHINY_COMPILER_MSVC
|
||||
|
||||
#elif defined (__GNUG__)
|
||||
# define SHINY_COMPILER SHINY_COMPILER_GNUC
|
||||
|
||||
#else
|
||||
# define SHINY_COMPILER SHINY_COMPILER_OTHER
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_GNUC
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
struct _ShinyNode;
|
||||
struct _ShinyZone;
|
||||
|
||||
typedef struct _ShinyNode* ShinyNodeCache;
|
||||
typedef struct _ShinyNode* ShinyNodeTable;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define SHINY_API
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
# define SHINY_INLINE __inline
|
||||
# define SHINY_UNUSED
|
||||
#elif SHINY_COMPILER == SHINY_COMPILER_GNUC
|
||||
# define SHINY_INLINE inline
|
||||
# define SHINY_UNUSED __attribute__((unused))
|
||||
#elif SHINY_COMPILER == SHINY_COMPILER_OTHER
|
||||
# define SHINY_INLINE inline
|
||||
# define SHINY_UNUSED
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if SHINY_COMPILER == SHINY_COMPILER_MSVC
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
/*
|
||||
#elif defined(__CYGWIN__)
|
||||
typedef u_int32_t uint32_t;
|
||||
typedef u_int64_t uint64_t;
|
||||
*/
|
||||
#endif
|
||||
|
||||
typedef uint64_t shinytick_t;
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_PREREQS_H */
|
||||
116
src/Shiny/ShinyTools.c
Normal file
116
src/Shiny/ShinyTools.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyTools.h"
|
||||
|
||||
#if SHINY_PLATFORM == SHINY_PLATFORM_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif /* NOMINMAX */
|
||||
#include <windows.h>
|
||||
|
||||
#elif SHINY_PLATFORM == SHINY_PLATFORM_POSIX
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
const ShinyTimeUnit* ShinyGetTimeUnit(float ticks) {
|
||||
static ShinyTimeUnit units[4] = { 0 };
|
||||
|
||||
if (units[0].tickFreq == 0) { /* auto initialize first time */
|
||||
units[0].tickFreq = ShinyGetTickFreq() / 1.0f;
|
||||
units[0].invTickFreq = ShinyGetTickInvFreq() * 1.0f;
|
||||
units[0].suffix = "s";
|
||||
|
||||
units[1].tickFreq = ShinyGetTickFreq() / 1000.0f;
|
||||
units[1].invTickFreq = ShinyGetTickInvFreq() * 1000.0f;
|
||||
units[1].suffix = "ms";
|
||||
|
||||
units[2].tickFreq = ShinyGetTickFreq() / 1000000.0f;
|
||||
units[2].invTickFreq = ShinyGetTickInvFreq() * 1000000.0f;
|
||||
units[2].suffix = "us";
|
||||
|
||||
units[3].tickFreq = ShinyGetTickFreq() / 1000000000.0f;
|
||||
units[3].invTickFreq = ShinyGetTickInvFreq() * 1000000000.0f;
|
||||
units[3].suffix = "ns";
|
||||
}
|
||||
|
||||
if (units[0].tickFreq < ticks) return &units[0];
|
||||
else if (units[1].tickFreq < ticks) return &units[1];
|
||||
else if (units[2].tickFreq < ticks) return &units[2];
|
||||
else return &units[3];
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if SHINY_PLATFORM == SHINY_PLATFORM_WIN32
|
||||
|
||||
void ShinyGetTicks(shinytick_t *p) {
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)(p));
|
||||
}
|
||||
|
||||
shinytick_t ShinyGetTickFreq(void) {
|
||||
static shinytick_t freq = 0;
|
||||
if (freq == 0) QueryPerformanceFrequency((LARGE_INTEGER*)(&freq));
|
||||
return freq;
|
||||
}
|
||||
|
||||
float ShinyGetTickInvFreq(void) {
|
||||
static float invfreq = 0;
|
||||
if (invfreq == 0) invfreq = 1.0f / ShinyGetTickFreq();
|
||||
return invfreq;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#elif SHINY_PLATFORM == SHINY_PLATFORM_POSIX
|
||||
|
||||
//#include <time.h>
|
||||
//#include <sys/time.h>
|
||||
|
||||
void ShinyGetTicks(shinytick_t *p) {
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
|
||||
*p = time.tv_sec * 1000000 + time.tv_usec;
|
||||
}
|
||||
|
||||
shinytick_t ShinyGetTickFreq(void) {
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
float ShinyGetTickInvFreq(void) {
|
||||
return 1.0f / 1000000.0f;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
57
src/Shiny/ShinyTools.h
Normal file
57
src/Shiny/ShinyTools.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_TOOLS_H
|
||||
#define SHINY_TOOLS_H
|
||||
|
||||
#include "ShinyPrereqs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
float tickFreq;
|
||||
float invTickFreq;
|
||||
const char* suffix;
|
||||
} ShinyTimeUnit;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_API const ShinyTimeUnit* ShinyGetTimeUnit(float ticks);
|
||||
|
||||
SHINY_API void ShinyGetTicks(shinytick_t *p);
|
||||
|
||||
SHINY_API shinytick_t ShinyGetTickFreq(void);
|
||||
|
||||
SHINY_API float ShinyGetTickInvFreq(void);
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SHINY_TOOLS_H */
|
||||
37
src/Shiny/ShinyVersion.h
Normal file
37
src/Shiny/ShinyVersion.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_VERSION_H
|
||||
#define SHINY_VERSION_H
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define SHINY_VERSION "2.6 RC1"
|
||||
#define SHINY_SHORTNAME "Shiny"
|
||||
#define SHINY_FULLNAME "Shiny Profiler"
|
||||
#define SHINY_COPYRIGHT "Copyright (C) 2007-2010 Aidin Abedi"
|
||||
#define SHINY_DESCRIPTION "Shiny is a state of the art profiler designed to help finding bottlenecks in your project."
|
||||
|
||||
#endif /* SHINY_VERSION_H */
|
||||
201
src/Shiny/ShinyZone.c
Normal file
201
src/Shiny/ShinyZone.c
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SLIC3R_PROFILE
|
||||
|
||||
#include "ShinyZone.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyZone_preUpdateChain(ShinyZone *first) {
|
||||
ShinyZone* zone = first;
|
||||
|
||||
while (zone) {
|
||||
ShinyData_clearCurrent(&(zone->data));
|
||||
zone = zone->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyZone_updateChain(ShinyZone *first, float a_damping) {
|
||||
ShinyZone* zone = first;
|
||||
|
||||
do {
|
||||
ShinyData_computeAverage(&(zone->data), a_damping);
|
||||
zone = zone->next;
|
||||
} while (zone);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyZone_updateChainClean(ShinyZone *first) {
|
||||
ShinyZone* zone = first;
|
||||
|
||||
do {
|
||||
ShinyData_copyAverage(&(zone->data));
|
||||
zone = zone->next;
|
||||
} while (zone);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyZone_resetChain(ShinyZone *first) {
|
||||
ShinyZone* zone = first, *temp;
|
||||
|
||||
do {
|
||||
zone->_state = SHINY_ZONE_STATE_HIDDEN;
|
||||
temp = zone->next;
|
||||
zone->next = NULL;
|
||||
zone = temp;
|
||||
} while (zone);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* A Linked-List Memory Sort
|
||||
by Philip J. Erdelsky
|
||||
pje@efgh.com
|
||||
http://www.alumni.caltech.edu/~pje/
|
||||
|
||||
Modified by Aidin Abedi
|
||||
*/
|
||||
|
||||
ShinyZone* ShinyZone_sortChain(ShinyZone **first) /* return ptr to last zone */
|
||||
{
|
||||
ShinyZone *p = *first;
|
||||
|
||||
unsigned base;
|
||||
unsigned long block_size;
|
||||
|
||||
struct tape
|
||||
{
|
||||
ShinyZone *first, *last;
|
||||
unsigned long count;
|
||||
} tape[4];
|
||||
|
||||
/* Distribute the records alternately to tape[0] and tape[1]. */
|
||||
|
||||
tape[0].count = tape[1].count = 0L;
|
||||
tape[0].first = NULL;
|
||||
base = 0;
|
||||
while (p != NULL)
|
||||
{
|
||||
ShinyZone *next = p->next;
|
||||
p->next = tape[base].first;
|
||||
tape[base].first = p;
|
||||
tape[base].count++;
|
||||
p = next;
|
||||
base ^= 1;
|
||||
}
|
||||
|
||||
/* If the list is empty or contains only a single record, then */
|
||||
/* tape[1].count == 0L and this part is vacuous. */
|
||||
|
||||
for (base = 0, block_size = 1L; tape[base+1].count != 0L;
|
||||
base ^= 2, block_size <<= 1)
|
||||
{
|
||||
int dest;
|
||||
struct tape *tape0, *tape1;
|
||||
tape0 = tape + base;
|
||||
tape1 = tape + base + 1;
|
||||
dest = base ^ 2;
|
||||
tape[dest].count = tape[dest+1].count = 0;
|
||||
for (; tape0->count != 0; dest ^= 1)
|
||||
{
|
||||
unsigned long n0, n1;
|
||||
struct tape *output_tape = tape + dest;
|
||||
n0 = n1 = block_size;
|
||||
while (1)
|
||||
{
|
||||
ShinyZone *chosen_record;
|
||||
struct tape *chosen_tape;
|
||||
if (n0 == 0 || tape0->count == 0)
|
||||
{
|
||||
if (n1 == 0 || tape1->count == 0)
|
||||
break;
|
||||
chosen_tape = tape1;
|
||||
n1--;
|
||||
}
|
||||
else if (n1 == 0 || tape1->count == 0)
|
||||
{
|
||||
chosen_tape = tape0;
|
||||
n0--;
|
||||
}
|
||||
else if (ShinyZone_compare(tape1->first, tape0->first) > 0)
|
||||
{
|
||||
chosen_tape = tape1;
|
||||
n1--;
|
||||
}
|
||||
else
|
||||
{
|
||||
chosen_tape = tape0;
|
||||
n0--;
|
||||
}
|
||||
chosen_tape->count--;
|
||||
chosen_record = chosen_tape->first;
|
||||
chosen_tape->first = chosen_record->next;
|
||||
if (output_tape->count == 0)
|
||||
output_tape->first = chosen_record;
|
||||
else
|
||||
output_tape->last->next = chosen_record;
|
||||
output_tape->last = chosen_record;
|
||||
output_tape->count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tape[base].count > 1L) {
|
||||
ShinyZone* last = tape[base].last;
|
||||
*first = tape[base].first;
|
||||
last->next = NULL;
|
||||
return last;
|
||||
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyZone_clear(ShinyZone* self) {
|
||||
memset(self, 0, sizeof(ShinyZone));
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void ShinyZone_enumerateZones(const ShinyZone* a_zone, void (*a_func)(const ShinyZone*)) {
|
||||
a_func(a_zone);
|
||||
|
||||
if (a_zone->next) ShinyZone_enumerateZones(a_zone->next, a_func);
|
||||
}
|
||||
|
||||
#endif /* SLIC3R_PROFILE */
|
||||
91
src/Shiny/ShinyZone.h
Normal file
91
src/Shiny/ShinyZone.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHINY_ZONE_H
|
||||
#define SHINY_ZONE_H
|
||||
|
||||
#include "ShinyData.h"
|
||||
#include <memory.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define SHINY_ZONE_STATE_HIDDEN 0
|
||||
#define SHINY_ZONE_STATE_INITIALIZED 1
|
||||
#define SHINY_ZONE_STATE_UPDATING 2
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct _ShinyZone {
|
||||
struct _ShinyZone* next;
|
||||
int _state;
|
||||
const char* name;
|
||||
ShinyData data;
|
||||
} ShinyZone;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
SHINY_INLINE void ShinyZone_init(ShinyZone *self, ShinyZone* a_prev) {
|
||||
self->_state = SHINY_ZONE_STATE_INITIALIZED;
|
||||
a_prev->next = self;
|
||||
}
|
||||
|
||||
SHINY_INLINE void ShinyZone_uninit(ShinyZone *self) {
|
||||
self->_state = SHINY_ZONE_STATE_HIDDEN;
|
||||
self->next = NULL;
|
||||
}
|
||||
|
||||
SHINY_API void ShinyZone_preUpdateChain(ShinyZone *first);
|
||||
SHINY_API void ShinyZone_updateChain(ShinyZone *first, float a_damping);
|
||||
SHINY_API void ShinyZone_updateChainClean(ShinyZone *first);
|
||||
|
||||
SHINY_API void ShinyZone_resetChain(ShinyZone *first);
|
||||
|
||||
SHINY_API ShinyZone* ShinyZone_sortChain(ShinyZone **first);
|
||||
|
||||
SHINY_INLINE float ShinyZone_compare(ShinyZone *a, ShinyZone *b) {
|
||||
return a->data.selfTicks.avg - b->data.selfTicks.avg;
|
||||
}
|
||||
|
||||
SHINY_API void ShinyZone_clear(ShinyZone* self);
|
||||
|
||||
SHINY_API void ShinyZone_enumerateZones(const ShinyZone* a_zone, void (*a_func)(const ShinyZone*));
|
||||
|
||||
#if __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
||||
template <class T>
|
||||
void ShinyZone_enumerateZones(const ShinyZone* a_zone, T* a_this, void (T::*a_func)(const ShinyZone*)) {
|
||||
(a_this->*a_func)(a_zone);
|
||||
|
||||
if (a_zone->next) ShinyZone_enumerateZones(a_zone->next, a_this, a_func);
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* SHINY_ZONE_H */
|
||||
12
src/admesh/CMakeLists.txt
Normal file
12
src/admesh/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
project(admesh)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
add_library(admesh STATIC
|
||||
connect.cpp
|
||||
normals.cpp
|
||||
shared.cpp
|
||||
stl.h
|
||||
stl_io.cpp
|
||||
stlinit.cpp
|
||||
util.cpp
|
||||
)
|
||||
911
src/admesh/connect.cpp
Normal file
911
src/admesh/connect.cpp
Normal file
|
|
@ -0,0 +1,911 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <boost/detail/endian.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
static void stl_match_neighbors_nearby(stl_file *stl,
|
||||
stl_hash_edge *edge_a, stl_hash_edge *edge_b);
|
||||
static void stl_record_neighbors(stl_file *stl,
|
||||
stl_hash_edge *edge_a, stl_hash_edge *edge_b);
|
||||
static void stl_initialize_facet_check_exact(stl_file *stl);
|
||||
static void stl_initialize_facet_check_nearby(stl_file *stl);
|
||||
static void stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge,
|
||||
stl_vertex *a, stl_vertex *b);
|
||||
static int stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge,
|
||||
stl_vertex *a, stl_vertex *b, float tolerance);
|
||||
static void insert_hash_edge(stl_file *stl, stl_hash_edge edge,
|
||||
void (*match_neighbors)(stl_file *stl,
|
||||
stl_hash_edge *edge_a, stl_hash_edge *edge_b));
|
||||
static int stl_compare_function(stl_hash_edge *edge_a, stl_hash_edge *edge_b);
|
||||
static void stl_free_edges(stl_file *stl);
|
||||
static void stl_remove_facet(stl_file *stl, int facet_number);
|
||||
static void stl_change_vertices(stl_file *stl, int facet_num, int vnot,
|
||||
stl_vertex new_vertex);
|
||||
static void stl_which_vertices_to_change(stl_file *stl, stl_hash_edge *edge_a,
|
||||
stl_hash_edge *edge_b, int *facet1, int *vertex1,
|
||||
int *facet2, int *vertex2,
|
||||
stl_vertex *new_vertex1, stl_vertex *new_vertex2);
|
||||
static void stl_remove_degenerate(stl_file *stl, int facet);
|
||||
extern int stl_check_normal_vector(stl_file *stl,
|
||||
int facet_num, int normal_fix_flag);
|
||||
static void stl_update_connects_remove_1(stl_file *stl, int facet_num);
|
||||
|
||||
|
||||
void
|
||||
stl_check_facets_exact(stl_file *stl) {
|
||||
/* This function builds the neighbors list. No modifications are made
|
||||
* to any of the facets. The edges are said to match only if all six
|
||||
* floats of the first edge matches all six floats of the second edge.
|
||||
*/
|
||||
|
||||
stl_hash_edge edge;
|
||||
stl_facet facet;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
stl->stats.connected_edges = 0;
|
||||
stl->stats.connected_facets_1_edge = 0;
|
||||
stl->stats.connected_facets_2_edge = 0;
|
||||
stl->stats.connected_facets_3_edge = 0;
|
||||
|
||||
stl_initialize_facet_check_exact(stl);
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
facet = stl->facet_start[i];
|
||||
// If any two of the three vertices are found to be exactally the same, call them degenerate and remove the facet.
|
||||
if (facet.vertex[0] == facet.vertex[1] ||
|
||||
facet.vertex[1] == facet.vertex[2] ||
|
||||
facet.vertex[0] == facet.vertex[2]) {
|
||||
stl->stats.degenerate_facets += 1;
|
||||
stl_remove_facet(stl, i);
|
||||
-- i;
|
||||
continue;
|
||||
}
|
||||
for(j = 0; j < 3; j++) {
|
||||
edge.facet_number = i;
|
||||
edge.which_edge = j;
|
||||
stl_load_edge_exact(stl, &edge, &facet.vertex[j], &facet.vertex[(j + 1) % 3]);
|
||||
insert_hash_edge(stl, edge, stl_record_neighbors);
|
||||
}
|
||||
}
|
||||
stl_free_edges(stl);
|
||||
|
||||
#if 0
|
||||
printf("Number of faces: %d, number of manifold edges: %d, number of connected edges: %d, number of unconnected edges: %d\r\n",
|
||||
stl->stats.number_of_facets, stl->stats.number_of_facets * 3,
|
||||
stl->stats.connected_edges, stl->stats.number_of_facets * 3 - stl->stats.connected_edges);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge,
|
||||
stl_vertex *a, stl_vertex *b) {
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
{
|
||||
stl_vertex diff = (*a - *b).cwiseAbs();
|
||||
float max_diff = std::max(diff(0), std::max(diff(1), diff(2)));
|
||||
stl->stats.shortest_edge = std::min(max_diff, stl->stats.shortest_edge);
|
||||
}
|
||||
|
||||
// Ensure identical vertex ordering of equal edges.
|
||||
// This method is numerically robust.
|
||||
if (stl_vertex_lower(*a, *b)) {
|
||||
} else {
|
||||
std::swap(a, b);
|
||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
||||
}
|
||||
memcpy(&edge->key[0], a->data(), sizeof(stl_vertex));
|
||||
memcpy(&edge->key[sizeof(stl_vertex)], b->data(), sizeof(stl_vertex));
|
||||
// Switch negative zeros to positive zeros, so memcmp will consider them to be equal.
|
||||
for (size_t i = 0; i < 6; ++ i) {
|
||||
unsigned char *p = edge->key + i * 4;
|
||||
#ifdef BOOST_LITTLE_ENDIAN
|
||||
if (p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0x80)
|
||||
// Negative zero, switch to positive zero.
|
||||
p[3] = 0;
|
||||
#else /* BOOST_LITTLE_ENDIAN */
|
||||
if (p[0] == 0x80 && p[1] == 0 && p[2] == 0 && p[3] == 0)
|
||||
// Negative zero, switch to positive zero.
|
||||
p[0] = 0;
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stl_initialize_facet_check_exact(stl_file *stl) {
|
||||
int i;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
stl->stats.malloced = 0;
|
||||
stl->stats.freed = 0;
|
||||
stl->stats.collisions = 0;
|
||||
|
||||
|
||||
stl->M = 81397;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets ; i++) {
|
||||
/* initialize neighbors list to -1 to mark unconnected edges */
|
||||
stl->neighbors_start[i].neighbor[0] = -1;
|
||||
stl->neighbors_start[i].neighbor[1] = -1;
|
||||
stl->neighbors_start[i].neighbor[2] = -1;
|
||||
}
|
||||
|
||||
stl->heads = (stl_hash_edge**)calloc(stl->M, sizeof(*stl->heads));
|
||||
if(stl->heads == NULL) perror("stl_initialize_facet_check_exact");
|
||||
|
||||
stl->tail = (stl_hash_edge*)malloc(sizeof(stl_hash_edge));
|
||||
if(stl->tail == NULL) perror("stl_initialize_facet_check_exact");
|
||||
|
||||
stl->tail->next = stl->tail;
|
||||
|
||||
for(i = 0; i < stl->M; i++) {
|
||||
stl->heads[i] = stl->tail;
|
||||
}
|
||||
}
|
||||
|
||||
static void insert_hash_edge(stl_file *stl, stl_hash_edge edge,
|
||||
void (*match_neighbors)(stl_file *stl,
|
||||
stl_hash_edge *edge_a, stl_hash_edge *edge_b))
|
||||
{
|
||||
if (stl->error) return;
|
||||
|
||||
int chain_number = edge.hash(stl->M);
|
||||
stl_hash_edge *link = stl->heads[chain_number];
|
||||
|
||||
stl_hash_edge *new_edge;
|
||||
stl_hash_edge *temp;
|
||||
if(link == stl->tail) {
|
||||
/* This list doesn't have any edges currently in it. Add this one. */
|
||||
new_edge = (stl_hash_edge*)malloc(sizeof(stl_hash_edge));
|
||||
if(new_edge == NULL) perror("insert_hash_edge");
|
||||
stl->stats.malloced++;
|
||||
*new_edge = edge;
|
||||
new_edge->next = stl->tail;
|
||||
stl->heads[chain_number] = new_edge;
|
||||
return;
|
||||
} else if(!stl_compare_function(&edge, link)) {
|
||||
/* This is a match. Record result in neighbors list. */
|
||||
match_neighbors(stl, &edge, link);
|
||||
/* Delete the matched edge from the list. */
|
||||
stl->heads[chain_number] = link->next;
|
||||
free(link);
|
||||
stl->stats.freed++;
|
||||
return;
|
||||
} else {
|
||||
/* Continue through the rest of the list */
|
||||
for(;;) {
|
||||
if(link->next == stl->tail) {
|
||||
/* This is the last item in the list. Insert a new edge. */
|
||||
new_edge = (stl_hash_edge*)malloc(sizeof(stl_hash_edge));
|
||||
if(new_edge == NULL) perror("insert_hash_edge");
|
||||
stl->stats.malloced++;
|
||||
*new_edge = edge;
|
||||
new_edge->next = stl->tail;
|
||||
link->next = new_edge;
|
||||
stl->stats.collisions++;
|
||||
return;
|
||||
} else if(!stl_compare_function(&edge, link->next)) {
|
||||
/* This is a match. Record result in neighbors list. */
|
||||
match_neighbors(stl, &edge, link->next);
|
||||
|
||||
/* Delete the matched edge from the list. */
|
||||
temp = link->next;
|
||||
link->next = link->next->next;
|
||||
free(temp);
|
||||
stl->stats.freed++;
|
||||
return;
|
||||
} else {
|
||||
/* This is not a match. Go to the next link */
|
||||
link = link->next;
|
||||
stl->stats.collisions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return 1 if the edges are not matched.
|
||||
static inline int stl_compare_function(stl_hash_edge *edge_a, stl_hash_edge *edge_b)
|
||||
{
|
||||
// Don't match edges of the same facet
|
||||
return (edge_a->facet_number == edge_b->facet_number) || (*edge_a != *edge_b);
|
||||
}
|
||||
|
||||
void stl_check_facets_nearby(stl_file *stl, float tolerance)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
if( (stl->stats.connected_facets_1_edge == stl->stats.number_of_facets)
|
||||
&& (stl->stats.connected_facets_2_edge == stl->stats.number_of_facets)
|
||||
&& (stl->stats.connected_facets_3_edge == stl->stats.number_of_facets)) {
|
||||
/* No need to check any further. All facets are connected */
|
||||
return;
|
||||
}
|
||||
|
||||
stl_initialize_facet_check_nearby(stl);
|
||||
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
//FIXME is the copy necessary?
|
||||
stl_facet facet = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if(stl->neighbors_start[i].neighbor[j] == -1) {
|
||||
stl_hash_edge edge;
|
||||
edge.facet_number = i;
|
||||
edge.which_edge = j;
|
||||
if(stl_load_edge_nearby(stl, &edge, &facet.vertex[j],
|
||||
&facet.vertex[(j + 1) % 3],
|
||||
tolerance)) {
|
||||
/* only insert edges that have different keys */
|
||||
insert_hash_edge(stl, edge, stl_match_neighbors_nearby);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stl_free_edges(stl);
|
||||
}
|
||||
|
||||
static int stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge, stl_vertex *a, stl_vertex *b, float tolerance)
|
||||
{
|
||||
// Index of a grid cell spaced by tolerance.
|
||||
typedef Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign> Vec3i;
|
||||
Vec3i vertex1 = (*a / tolerance).cast<int32_t>();
|
||||
Vec3i vertex2 = (*b / tolerance).cast<int32_t>();
|
||||
static_assert(sizeof(Vec3i) == 12, "size of Vec3i incorrect");
|
||||
|
||||
if (vertex1 == vertex2)
|
||||
// Both vertices hash to the same value
|
||||
return 0;
|
||||
|
||||
// Ensure identical vertex ordering of edges, which vertices land into equal grid cells.
|
||||
// This method is numerically robust.
|
||||
if ((vertex1[0] != vertex2[0]) ?
|
||||
(vertex1[0] < vertex2[0]) :
|
||||
((vertex1[1] != vertex2[1]) ?
|
||||
(vertex1[1] < vertex2[1]) :
|
||||
(vertex1[2] < vertex2[2]))) {
|
||||
memcpy(&edge->key[0], vertex1.data(), sizeof(stl_vertex));
|
||||
memcpy(&edge->key[sizeof(stl_vertex)], vertex2.data(), sizeof(stl_vertex));
|
||||
} else {
|
||||
memcpy(&edge->key[0], vertex2.data(), sizeof(stl_vertex));
|
||||
memcpy(&edge->key[sizeof(stl_vertex)], vertex1.data(), sizeof(stl_vertex));
|
||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void stl_free_edges(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
if(stl->stats.malloced != stl->stats.freed) {
|
||||
for (int i = 0; i < stl->M; i++) {
|
||||
for (stl_hash_edge *temp = stl->heads[i]; stl->heads[i] != stl->tail; temp = stl->heads[i]) {
|
||||
stl->heads[i] = stl->heads[i]->next;
|
||||
free(temp);
|
||||
++ stl->stats.freed;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(stl->heads);
|
||||
free(stl->tail);
|
||||
}
|
||||
|
||||
static void stl_initialize_facet_check_nearby(stl_file *stl)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
stl->stats.malloced = 0;
|
||||
stl->stats.freed = 0;
|
||||
stl->stats.collisions = 0;
|
||||
|
||||
/* tolerance = STL_MAX(stl->stats.shortest_edge, tolerance);*/
|
||||
/* tolerance = STL_MAX((stl->stats.bounding_diameter / 500000.0), tolerance);*/
|
||||
/* tolerance *= 0.5;*/
|
||||
|
||||
stl->M = 81397;
|
||||
|
||||
stl->heads = (stl_hash_edge**)calloc(stl->M, sizeof(*stl->heads));
|
||||
if(stl->heads == NULL) perror("stl_initialize_facet_check_nearby");
|
||||
|
||||
stl->tail = (stl_hash_edge*)malloc(sizeof(stl_hash_edge));
|
||||
if(stl->tail == NULL) perror("stl_initialize_facet_check_nearby");
|
||||
|
||||
stl->tail->next = stl->tail;
|
||||
|
||||
for(i = 0; i < stl->M; i++) {
|
||||
stl->heads[i] = stl->tail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
stl_record_neighbors(stl_file *stl,
|
||||
stl_hash_edge *edge_a, stl_hash_edge *edge_b) {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Facet a's neighbor is facet b */
|
||||
stl->neighbors_start[edge_a->facet_number].neighbor[edge_a->which_edge % 3] =
|
||||
edge_b->facet_number; /* sets the .neighbor part */
|
||||
|
||||
stl->neighbors_start[edge_a->facet_number].
|
||||
which_vertex_not[edge_a->which_edge % 3] =
|
||||
(edge_b->which_edge + 2) % 3; /* sets the .which_vertex_not part */
|
||||
|
||||
/* Facet b's neighbor is facet a */
|
||||
stl->neighbors_start[edge_b->facet_number].neighbor[edge_b->which_edge % 3] =
|
||||
edge_a->facet_number; /* sets the .neighbor part */
|
||||
|
||||
stl->neighbors_start[edge_b->facet_number].
|
||||
which_vertex_not[edge_b->which_edge % 3] =
|
||||
(edge_a->which_edge + 2) % 3; /* sets the .which_vertex_not part */
|
||||
|
||||
if( ((edge_a->which_edge < 3) && (edge_b->which_edge < 3))
|
||||
|| ((edge_a->which_edge > 2) && (edge_b->which_edge > 2))) {
|
||||
/* these facets are oriented in opposite directions. */
|
||||
/* their normals are probably messed up. */
|
||||
stl->neighbors_start[edge_a->facet_number].
|
||||
which_vertex_not[edge_a->which_edge % 3] += 3;
|
||||
stl->neighbors_start[edge_b->facet_number].
|
||||
which_vertex_not[edge_b->which_edge % 3] += 3;
|
||||
}
|
||||
|
||||
|
||||
/* Count successful connects */
|
||||
/* Total connects */
|
||||
stl->stats.connected_edges += 2;
|
||||
/* Count individual connects */
|
||||
i = ((stl->neighbors_start[edge_a->facet_number].neighbor[0] == -1) +
|
||||
(stl->neighbors_start[edge_a->facet_number].neighbor[1] == -1) +
|
||||
(stl->neighbors_start[edge_a->facet_number].neighbor[2] == -1));
|
||||
j = ((stl->neighbors_start[edge_b->facet_number].neighbor[0] == -1) +
|
||||
(stl->neighbors_start[edge_b->facet_number].neighbor[1] == -1) +
|
||||
(stl->neighbors_start[edge_b->facet_number].neighbor[2] == -1));
|
||||
if(i == 2) {
|
||||
stl->stats.connected_facets_1_edge +=1;
|
||||
} else if(i == 1) {
|
||||
stl->stats.connected_facets_2_edge +=1;
|
||||
} else {
|
||||
stl->stats.connected_facets_3_edge +=1;
|
||||
}
|
||||
if(j == 2) {
|
||||
stl->stats.connected_facets_1_edge +=1;
|
||||
} else if(j == 1) {
|
||||
stl->stats.connected_facets_2_edge +=1;
|
||||
} else {
|
||||
stl->stats.connected_facets_3_edge +=1;
|
||||
}
|
||||
}
|
||||
|
||||
static void stl_match_neighbors_nearby(stl_file *stl, stl_hash_edge *edge_a, stl_hash_edge *edge_b)
|
||||
{
|
||||
int facet1;
|
||||
int facet2;
|
||||
int vertex1;
|
||||
int vertex2;
|
||||
int vnot1;
|
||||
int vnot2;
|
||||
stl_vertex new_vertex1;
|
||||
stl_vertex new_vertex2;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
stl_record_neighbors(stl, edge_a, edge_b);
|
||||
stl_which_vertices_to_change(stl, edge_a, edge_b, &facet1, &vertex1,
|
||||
&facet2, &vertex2, &new_vertex1, &new_vertex2);
|
||||
if(facet1 != -1) {
|
||||
if(facet1 == edge_a->facet_number) {
|
||||
vnot1 = (edge_a->which_edge + 2) % 3;
|
||||
} else {
|
||||
vnot1 = (edge_b->which_edge + 2) % 3;
|
||||
}
|
||||
if(((vnot1 + 2) % 3) == vertex1) {
|
||||
vnot1 += 3;
|
||||
}
|
||||
stl_change_vertices(stl, facet1, vnot1, new_vertex1);
|
||||
}
|
||||
if(facet2 != -1) {
|
||||
if(facet2 == edge_a->facet_number) {
|
||||
vnot2 = (edge_a->which_edge + 2) % 3;
|
||||
} else {
|
||||
vnot2 = (edge_b->which_edge + 2) % 3;
|
||||
}
|
||||
if(((vnot2 + 2) % 3) == vertex2) {
|
||||
vnot2 += 3;
|
||||
}
|
||||
stl_change_vertices(stl, facet2, vnot2, new_vertex2);
|
||||
}
|
||||
stl->stats.edges_fixed += 2;
|
||||
}
|
||||
|
||||
|
||||
static void stl_change_vertices(stl_file *stl, int facet_num, int vnot, stl_vertex new_vertex) {
|
||||
int first_facet;
|
||||
int direction;
|
||||
int next_edge;
|
||||
int pivot_vertex;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
first_facet = facet_num;
|
||||
direction = 0;
|
||||
|
||||
for(;;) {
|
||||
if(vnot > 2) {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
direction = 1;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
direction = 0;
|
||||
}
|
||||
} else {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) == new_vertex(0) &&
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](1) == new_vertex(1) &&
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](2) == new_vertex(2))
|
||||
printf("Changing vertex %f,%f,%f: Same !!!\r\n",
|
||||
new_vertex(0), new_vertex(1), new_vertex(2));
|
||||
else {
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) != new_vertex(0))
|
||||
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](0),
|
||||
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](0)),
|
||||
new_vertex(0),
|
||||
*reinterpret_cast<const int*>(&new_vertex(0)));
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](1) != new_vertex(1))
|
||||
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](1),
|
||||
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](1)),
|
||||
new_vertex(1),
|
||||
*reinterpret_cast<const int*>(&new_vertex(1)));
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](2) != new_vertex(2))
|
||||
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](2),
|
||||
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](2)),
|
||||
new_vertex(2),
|
||||
*reinterpret_cast<const int*>(&new_vertex(2)));
|
||||
}
|
||||
#endif
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex] = new_vertex;
|
||||
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
|
||||
facet_num = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||
|
||||
if(facet_num == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(facet_num == first_facet) {
|
||||
/* back to the beginning */
|
||||
printf("\
|
||||
Back to the first facet changing vertices: probably a mobius part.\n\
|
||||
Try using a smaller tolerance or don't do a nearby check\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stl_which_vertices_to_change(stl_file *stl, stl_hash_edge *edge_a,
|
||||
stl_hash_edge *edge_b, int *facet1, int *vertex1,
|
||||
int *facet2, int *vertex2,
|
||||
stl_vertex *new_vertex1, stl_vertex *new_vertex2) {
|
||||
int v1a; /* pair 1, facet a */
|
||||
int v1b; /* pair 1, facet b */
|
||||
int v2a; /* pair 2, facet a */
|
||||
int v2b; /* pair 2, facet b */
|
||||
|
||||
/* Find first pair */
|
||||
if(edge_a->which_edge < 3) {
|
||||
v1a = edge_a->which_edge;
|
||||
v2a = (edge_a->which_edge + 1) % 3;
|
||||
} else {
|
||||
v2a = edge_a->which_edge % 3;
|
||||
v1a = (edge_a->which_edge + 1) % 3;
|
||||
}
|
||||
if(edge_b->which_edge < 3) {
|
||||
v1b = edge_b->which_edge;
|
||||
v2b = (edge_b->which_edge + 1) % 3;
|
||||
} else {
|
||||
v2b = edge_b->which_edge % 3;
|
||||
v1b = (edge_b->which_edge + 1) % 3;
|
||||
}
|
||||
|
||||
// Of the first pair, which vertex, if any, should be changed
|
||||
if(stl->facet_start[edge_a->facet_number].vertex[v1a] ==
|
||||
stl->facet_start[edge_b->facet_number].vertex[v1b]) {
|
||||
// These facets are already equal. No need to change.
|
||||
*facet1 = -1;
|
||||
} else {
|
||||
if( (stl->neighbors_start[edge_a->facet_number].neighbor[v1a] == -1)
|
||||
&& (stl->neighbors_start[edge_a->facet_number].
|
||||
neighbor[(v1a + 2) % 3] == -1)) {
|
||||
/* This vertex has no neighbors. This is a good one to change */
|
||||
*facet1 = edge_a->facet_number;
|
||||
*vertex1 = v1a;
|
||||
*new_vertex1 = stl->facet_start[edge_b->facet_number].vertex[v1b];
|
||||
} else {
|
||||
*facet1 = edge_b->facet_number;
|
||||
*vertex1 = v1b;
|
||||
*new_vertex1 = stl->facet_start[edge_a->facet_number].vertex[v1a];
|
||||
}
|
||||
}
|
||||
|
||||
/* Of the second pair, which vertex, if any, should be changed */
|
||||
if(stl->facet_start[edge_a->facet_number].vertex[v2a] ==
|
||||
stl->facet_start[edge_b->facet_number].vertex[v2b]) {
|
||||
// These facets are already equal. No need to change.
|
||||
*facet2 = -1;
|
||||
} else {
|
||||
if( (stl->neighbors_start[edge_a->facet_number].neighbor[v2a] == -1)
|
||||
&& (stl->neighbors_start[edge_a->facet_number].
|
||||
neighbor[(v2a + 2) % 3] == -1)) {
|
||||
/* This vertex has no neighbors. This is a good one to change */
|
||||
*facet2 = edge_a->facet_number;
|
||||
*vertex2 = v2a;
|
||||
*new_vertex2 = stl->facet_start[edge_b->facet_number].vertex[v2b];
|
||||
} else {
|
||||
*facet2 = edge_b->facet_number;
|
||||
*vertex2 = v2b;
|
||||
*new_vertex2 = stl->facet_start[edge_a->facet_number].vertex[v2a];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stl_remove_facet(stl_file *stl, int facet_number) {
|
||||
int neighbor[3];
|
||||
int vnot[3];
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
stl->stats.facets_removed += 1;
|
||||
/* Update list of connected edges */
|
||||
j = ((stl->neighbors_start[facet_number].neighbor[0] == -1) +
|
||||
(stl->neighbors_start[facet_number].neighbor[1] == -1) +
|
||||
(stl->neighbors_start[facet_number].neighbor[2] == -1));
|
||||
if(j == 2) {
|
||||
stl->stats.connected_facets_1_edge -= 1;
|
||||
} else if(j == 1) {
|
||||
stl->stats.connected_facets_2_edge -= 1;
|
||||
stl->stats.connected_facets_1_edge -= 1;
|
||||
} else if(j == 0) {
|
||||
stl->stats.connected_facets_3_edge -= 1;
|
||||
stl->stats.connected_facets_2_edge -= 1;
|
||||
stl->stats.connected_facets_1_edge -= 1;
|
||||
}
|
||||
|
||||
stl->facet_start[facet_number] =
|
||||
stl->facet_start[stl->stats.number_of_facets - 1];
|
||||
/* I could reallocate at this point, but it is not really necessary. */
|
||||
stl->neighbors_start[facet_number] =
|
||||
stl->neighbors_start[stl->stats.number_of_facets - 1];
|
||||
stl->stats.number_of_facets -= 1;
|
||||
|
||||
for(i = 0; i < 3; i++) {
|
||||
neighbor[i] = stl->neighbors_start[facet_number].neighbor[i];
|
||||
vnot[i] = stl->neighbors_start[facet_number].which_vertex_not[i];
|
||||
}
|
||||
|
||||
for(i = 0; i < 3; i++) {
|
||||
if(neighbor[i] != -1) {
|
||||
if(stl->neighbors_start[neighbor[i]].neighbor[(vnot[i] + 1)% 3] !=
|
||||
stl->stats.number_of_facets) {
|
||||
printf("\
|
||||
in stl_remove_facet: neighbor = %d numfacets = %d this is wrong\n",
|
||||
stl->neighbors_start[neighbor[i]].neighbor[(vnot[i] + 1)% 3],
|
||||
stl->stats.number_of_facets);
|
||||
return;
|
||||
}
|
||||
stl->neighbors_start[neighbor[i]].neighbor[(vnot[i] + 1)% 3]
|
||||
= facet_number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stl_remove_unconnected_facets(stl_file *stl)
|
||||
{
|
||||
/* A couple of things need to be done here. One is to remove any */
|
||||
/* completely unconnected facets (0 edges connected) since these are */
|
||||
/* useless and could be completely wrong. The second thing that needs to */
|
||||
/* be done is to remove any degenerate facets that were created during */
|
||||
/* stl_check_facets_nearby(). */
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
// remove degenerate facets
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
if(stl->facet_start[i].vertex[0] == stl->facet_start[i].vertex[1] ||
|
||||
stl->facet_start[i].vertex[0] == stl->facet_start[i].vertex[2] ||
|
||||
stl->facet_start[i].vertex[1] == stl->facet_start[i].vertex[2]) {
|
||||
stl_remove_degenerate(stl, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if(stl->stats.connected_facets_1_edge < stl->stats.number_of_facets) {
|
||||
// remove completely unconnected facets
|
||||
for (int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
if (stl->neighbors_start[i].neighbor[0] == -1 &&
|
||||
stl->neighbors_start[i].neighbor[1] == -1 &&
|
||||
stl->neighbors_start[i].neighbor[2] == -1) {
|
||||
// This facet is completely unconnected. Remove it.
|
||||
stl_remove_facet(stl, i);
|
||||
-- i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stl_remove_degenerate(stl_file *stl, int facet) {
|
||||
int edge1;
|
||||
int edge2;
|
||||
int edge3;
|
||||
int neighbor1;
|
||||
int neighbor2;
|
||||
int neighbor3;
|
||||
int vnot1;
|
||||
int vnot2;
|
||||
int vnot3;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
if (stl->facet_start[facet].vertex[0] == stl->facet_start[facet].vertex[1] &&
|
||||
stl->facet_start[facet].vertex[1] == stl->facet_start[facet].vertex[2]) {
|
||||
/* all 3 vertices are equal. Just remove the facet. I don't think*/
|
||||
/* this is really possible, but just in case... */
|
||||
printf("removing a facet in stl_remove_degenerate\n");
|
||||
stl_remove_facet(stl, facet);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stl->facet_start[facet].vertex[0] == stl->facet_start[facet].vertex[1]) {
|
||||
edge1 = 1;
|
||||
edge2 = 2;
|
||||
edge3 = 0;
|
||||
} else if (stl->facet_start[facet].vertex[1] == stl->facet_start[facet].vertex[2]) {
|
||||
edge1 = 0;
|
||||
edge2 = 2;
|
||||
edge3 = 1;
|
||||
} else if (stl->facet_start[facet].vertex[2] == stl->facet_start[facet].vertex[0]) {
|
||||
edge1 = 0;
|
||||
edge2 = 1;
|
||||
edge3 = 2;
|
||||
} else {
|
||||
/* No degenerate. Function shouldn't have been called. */
|
||||
return;
|
||||
}
|
||||
neighbor1 = stl->neighbors_start[facet].neighbor[edge1];
|
||||
neighbor2 = stl->neighbors_start[facet].neighbor[edge2];
|
||||
|
||||
if(neighbor1 == -1) {
|
||||
stl_update_connects_remove_1(stl, neighbor2);
|
||||
}
|
||||
if(neighbor2 == -1) {
|
||||
stl_update_connects_remove_1(stl, neighbor1);
|
||||
}
|
||||
|
||||
|
||||
neighbor3 = stl->neighbors_start[facet].neighbor[edge3];
|
||||
vnot1 = stl->neighbors_start[facet].which_vertex_not[edge1];
|
||||
vnot2 = stl->neighbors_start[facet].which_vertex_not[edge2];
|
||||
vnot3 = stl->neighbors_start[facet].which_vertex_not[edge3];
|
||||
|
||||
if(neighbor1 >= 0){
|
||||
stl->neighbors_start[neighbor1].neighbor[(vnot1 + 1) % 3] = neighbor2;
|
||||
stl->neighbors_start[neighbor1].which_vertex_not[(vnot1 + 1) % 3] = vnot2;
|
||||
}
|
||||
if(neighbor2 >= 0){
|
||||
stl->neighbors_start[neighbor2].neighbor[(vnot2 + 1) % 3] = neighbor1;
|
||||
stl->neighbors_start[neighbor2].which_vertex_not[(vnot2 + 1) % 3] = vnot1;
|
||||
}
|
||||
|
||||
stl_remove_facet(stl, facet);
|
||||
|
||||
if(neighbor3 >= 0) {
|
||||
stl_update_connects_remove_1(stl, neighbor3);
|
||||
stl->neighbors_start[neighbor3].neighbor[(vnot3 + 1) % 3] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_update_connects_remove_1(stl_file *stl, int facet_num) {
|
||||
int j;
|
||||
|
||||
if (stl->error) return;
|
||||
/* Update list of connected edges */
|
||||
j = ((stl->neighbors_start[facet_num].neighbor[0] == -1) +
|
||||
(stl->neighbors_start[facet_num].neighbor[1] == -1) +
|
||||
(stl->neighbors_start[facet_num].neighbor[2] == -1));
|
||||
if(j == 0) { /* Facet has 3 neighbors */
|
||||
stl->stats.connected_facets_3_edge -= 1;
|
||||
} else if(j == 1) { /* Facet has 2 neighbors */
|
||||
stl->stats.connected_facets_2_edge -= 1;
|
||||
} else if(j == 2) { /* Facet has 1 neighbor */
|
||||
stl->stats.connected_facets_1_edge -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_fill_holes(stl_file *stl) {
|
||||
stl_facet facet;
|
||||
stl_facet new_facet;
|
||||
int neighbors_initial[3];
|
||||
stl_hash_edge edge;
|
||||
int first_facet;
|
||||
int direction;
|
||||
int facet_num;
|
||||
int vnot;
|
||||
int next_edge;
|
||||
int pivot_vertex;
|
||||
int next_facet;
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Insert all unconnected edges into hash list */
|
||||
stl_initialize_facet_check_nearby(stl);
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
facet = stl->facet_start[i];
|
||||
for(j = 0; j < 3; j++) {
|
||||
if(stl->neighbors_start[i].neighbor[j] != -1) continue;
|
||||
edge.facet_number = i;
|
||||
edge.which_edge = j;
|
||||
stl_load_edge_exact(stl, &edge, &facet.vertex[j],
|
||||
&facet.vertex[(j + 1) % 3]);
|
||||
|
||||
insert_hash_edge(stl, edge, stl_record_neighbors);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
facet = stl->facet_start[i];
|
||||
neighbors_initial[0] = stl->neighbors_start[i].neighbor[0];
|
||||
neighbors_initial[1] = stl->neighbors_start[i].neighbor[1];
|
||||
neighbors_initial[2] = stl->neighbors_start[i].neighbor[2];
|
||||
first_facet = i;
|
||||
for(j = 0; j < 3; j++) {
|
||||
if(stl->neighbors_start[i].neighbor[j] != -1) continue;
|
||||
|
||||
new_facet.vertex[0] = facet.vertex[j];
|
||||
new_facet.vertex[1] = facet.vertex[(j + 1) % 3];
|
||||
if(neighbors_initial[(j + 2) % 3] == -1) {
|
||||
direction = 1;
|
||||
} else {
|
||||
direction = 0;
|
||||
}
|
||||
|
||||
facet_num = i;
|
||||
vnot = (j + 2) % 3;
|
||||
|
||||
for(;;) {
|
||||
if(vnot > 2) {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
direction = 1;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
direction = 0;
|
||||
}
|
||||
} else {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
}
|
||||
next_facet = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||
|
||||
if(next_facet == -1) {
|
||||
new_facet.vertex[2] = stl->facet_start[facet_num].
|
||||
vertex[vnot % 3];
|
||||
stl_add_facet(stl, &new_facet);
|
||||
for(k = 0; k < 3; k++) {
|
||||
edge.facet_number = stl->stats.number_of_facets - 1;
|
||||
edge.which_edge = k;
|
||||
stl_load_edge_exact(stl, &edge, &new_facet.vertex[k],
|
||||
&new_facet.vertex[(k + 1) % 3]);
|
||||
|
||||
insert_hash_edge(stl, edge, stl_record_neighbors);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
vnot = stl->neighbors_start[facet_num].
|
||||
which_vertex_not[next_edge];
|
||||
facet_num = next_facet;
|
||||
}
|
||||
|
||||
if(facet_num == first_facet) {
|
||||
/* back to the beginning */
|
||||
printf("\
|
||||
Back to the first facet filling holes: probably a mobius part.\n\
|
||||
Try using a smaller tolerance or don't do a nearby check\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_add_facet(stl_file *stl, stl_facet *new_facet) {
|
||||
if (stl->error) return;
|
||||
|
||||
stl->stats.facets_added += 1;
|
||||
if(stl->stats.facets_malloced < stl->stats.number_of_facets + 1) {
|
||||
stl->facet_start = (stl_facet*)realloc(stl->facet_start,
|
||||
(sizeof(stl_facet) * (stl->stats.facets_malloced + 256)));
|
||||
if(stl->facet_start == NULL) perror("stl_add_facet");
|
||||
stl->neighbors_start = (stl_neighbors*)realloc(stl->neighbors_start,
|
||||
(sizeof(stl_neighbors) * (stl->stats.facets_malloced + 256)));
|
||||
if(stl->neighbors_start == NULL) perror("stl_add_facet");
|
||||
stl->stats.facets_malloced += 256;
|
||||
}
|
||||
stl->facet_start[stl->stats.number_of_facets] = *new_facet;
|
||||
|
||||
/* note that the normal vector is not set here, just initialized to 0 */
|
||||
stl->facet_start[stl->stats.number_of_facets].normal = stl_normal::Zero();
|
||||
|
||||
stl->neighbors_start[stl->stats.number_of_facets].neighbor[0] = -1;
|
||||
stl->neighbors_start[stl->stats.number_of_facets].neighbor[1] = -1;
|
||||
stl->neighbors_start[stl->stats.number_of_facets].neighbor[2] = -1;
|
||||
stl->stats.number_of_facets += 1;
|
||||
}
|
||||
292
src/admesh/normals.cpp
Normal file
292
src/admesh/normals.cpp
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag);
|
||||
|
||||
static void
|
||||
stl_reverse_facet(stl_file *stl, int facet_num) {
|
||||
stl_vertex tmp_vertex;
|
||||
/* int tmp_neighbor;*/
|
||||
int neighbor[3];
|
||||
int vnot[3];
|
||||
|
||||
stl->stats.facets_reversed += 1;
|
||||
|
||||
neighbor[0] = stl->neighbors_start[facet_num].neighbor[0];
|
||||
neighbor[1] = stl->neighbors_start[facet_num].neighbor[1];
|
||||
neighbor[2] = stl->neighbors_start[facet_num].neighbor[2];
|
||||
vnot[0] = stl->neighbors_start[facet_num].which_vertex_not[0];
|
||||
vnot[1] = stl->neighbors_start[facet_num].which_vertex_not[1];
|
||||
vnot[2] = stl->neighbors_start[facet_num].which_vertex_not[2];
|
||||
|
||||
/* reverse the facet */
|
||||
tmp_vertex = stl->facet_start[facet_num].vertex[0];
|
||||
stl->facet_start[facet_num].vertex[0] =
|
||||
stl->facet_start[facet_num].vertex[1];
|
||||
stl->facet_start[facet_num].vertex[1] = tmp_vertex;
|
||||
|
||||
/* fix the vnots of the neighboring facets */
|
||||
if(neighbor[0] != -1)
|
||||
stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] =
|
||||
(stl->neighbors_start[neighbor[0]].
|
||||
which_vertex_not[(vnot[0] + 1) % 3] + 3) % 6;
|
||||
if(neighbor[1] != -1)
|
||||
stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] =
|
||||
(stl->neighbors_start[neighbor[1]].
|
||||
which_vertex_not[(vnot[1] + 1) % 3] + 4) % 6;
|
||||
if(neighbor[2] != -1)
|
||||
stl->neighbors_start[neighbor[2]].which_vertex_not[(vnot[2] + 1) % 3] =
|
||||
(stl->neighbors_start[neighbor[2]].
|
||||
which_vertex_not[(vnot[2] + 1) % 3] + 2) % 6;
|
||||
|
||||
/* swap the neighbors of the facet that is being reversed */
|
||||
stl->neighbors_start[facet_num].neighbor[1] = neighbor[2];
|
||||
stl->neighbors_start[facet_num].neighbor[2] = neighbor[1];
|
||||
|
||||
/* swap the vnots of the facet that is being reversed */
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] = vnot[2];
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] = vnot[1];
|
||||
|
||||
/* reverse the values of the vnots of the facet that is being reversed */
|
||||
stl->neighbors_start[facet_num].which_vertex_not[0] =
|
||||
(stl->neighbors_start[facet_num].which_vertex_not[0] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] =
|
||||
(stl->neighbors_start[facet_num].which_vertex_not[1] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] =
|
||||
(stl->neighbors_start[facet_num].which_vertex_not[2] + 3) % 6;
|
||||
}
|
||||
|
||||
void
|
||||
stl_fix_normal_directions(stl_file *stl) {
|
||||
char *norm_sw;
|
||||
/* int edge_num;*/
|
||||
/* int vnot;*/
|
||||
int checked = 0;
|
||||
int facet_num;
|
||||
/* int next_facet;*/
|
||||
int i;
|
||||
int j;
|
||||
struct stl_normal {
|
||||
int facet_num;
|
||||
struct stl_normal *next;
|
||||
};
|
||||
struct stl_normal *head;
|
||||
struct stl_normal *tail;
|
||||
struct stl_normal *newn;
|
||||
struct stl_normal *temp;
|
||||
|
||||
int* reversed_ids;
|
||||
int reversed_count = 0;
|
||||
int id;
|
||||
int force_exit = 0;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Initialize linked list. */
|
||||
head = (struct stl_normal*)malloc(sizeof(struct stl_normal));
|
||||
if(head == NULL) perror("stl_fix_normal_directions");
|
||||
tail = (struct stl_normal*)malloc(sizeof(struct stl_normal));
|
||||
if(tail == NULL) perror("stl_fix_normal_directions");
|
||||
head->next = tail;
|
||||
tail->next = tail;
|
||||
|
||||
/* Initialize list that keeps track of already fixed facets. */
|
||||
norm_sw = (char*)calloc(stl->stats.number_of_facets, sizeof(char));
|
||||
if(norm_sw == NULL) perror("stl_fix_normal_directions");
|
||||
|
||||
/* Initialize list that keeps track of reversed facets. */
|
||||
reversed_ids = (int*)calloc(stl->stats.number_of_facets, sizeof(int));
|
||||
if (reversed_ids == NULL) perror("stl_fix_normal_directions reversed_ids");
|
||||
|
||||
facet_num = 0;
|
||||
/* If normal vector is not within tolerance and backwards:
|
||||
Arbitrarily starts at face 0. If this one is wrong, we're screwed. Thankfully, the chances
|
||||
of it being wrong randomly are low if most of the triangles are right: */
|
||||
if (stl_check_normal_vector(stl, 0, 0) == 2) {
|
||||
stl_reverse_facet(stl, 0);
|
||||
reversed_ids[reversed_count++] = 0;
|
||||
}
|
||||
|
||||
/* Say that we've fixed this facet: */
|
||||
norm_sw[facet_num] = 1;
|
||||
checked++;
|
||||
|
||||
for(;;) {
|
||||
/* Add neighbors_to_list.
|
||||
Add unconnected neighbors to the list:a */
|
||||
for(j = 0; j < 3; j++) {
|
||||
/* Reverse the neighboring facets if necessary. */
|
||||
if(stl->neighbors_start[facet_num].which_vertex_not[j] > 2) {
|
||||
/* If the facet has a neighbor that is -1, it means that edge isn't shared by another facet */
|
||||
if(stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] == 1) {
|
||||
/* trying to modify a facet already marked as fixed, revert all changes made until now and exit (fixes: #716, #574, #413, #269, #262, #259, #230, #228, #206) */
|
||||
for (id = reversed_count - 1; id >= 0; --id) {
|
||||
stl_reverse_facet(stl, reversed_ids[id]);
|
||||
}
|
||||
force_exit = 1;
|
||||
break;
|
||||
} else {
|
||||
stl_reverse_facet(stl, stl->neighbors_start[facet_num].neighbor[j]);
|
||||
reversed_ids[reversed_count++] = stl->neighbors_start[facet_num].neighbor[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If this edge of the facet is connected: */
|
||||
if(stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
/* If we haven't fixed this facet yet, add it to the list: */
|
||||
if(norm_sw[stl->neighbors_start[facet_num].neighbor[j]] != 1) {
|
||||
/* Add node to beginning of list. */
|
||||
newn = (struct stl_normal*)malloc(sizeof(struct stl_normal));
|
||||
if(newn == NULL) perror("stl_fix_normal_directions");
|
||||
newn->facet_num = stl->neighbors_start[facet_num].neighbor[j];
|
||||
newn->next = head->next;
|
||||
head->next = newn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* an error occourred, quit the for loop and exit */
|
||||
if (force_exit) break;
|
||||
|
||||
/* Get next facet to fix from top of list. */
|
||||
if(head->next != tail) {
|
||||
facet_num = head->next->facet_num;
|
||||
if(norm_sw[facet_num] != 1) { /* If facet is in list mutiple times */
|
||||
norm_sw[facet_num] = 1; /* Record this one as being fixed. */
|
||||
checked++;
|
||||
}
|
||||
temp = head->next; /* Delete this facet from the list. */
|
||||
head->next = head->next->next;
|
||||
free(temp);
|
||||
} else { /* if we ran out of facets to fix: */
|
||||
/* All of the facets in this part have been fixed. */
|
||||
stl->stats.number_of_parts += 1;
|
||||
if(checked >= stl->stats.number_of_facets) {
|
||||
/* All of the facets have been checked. Bail out. */
|
||||
break;
|
||||
} else {
|
||||
/* There is another part here. Find it and continue. */
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
if(norm_sw[i] == 0) {
|
||||
/* This is the first facet of the next part. */
|
||||
facet_num = i;
|
||||
if(stl_check_normal_vector(stl, i, 0) == 2) {
|
||||
stl_reverse_facet(stl, i);
|
||||
reversed_ids[reversed_count++] = i;
|
||||
}
|
||||
|
||||
norm_sw[facet_num] = 1;
|
||||
checked++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(head);
|
||||
free(tail);
|
||||
free(reversed_ids);
|
||||
free(norm_sw);
|
||||
}
|
||||
|
||||
static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag) {
|
||||
/* Returns 0 if the normal is within tolerance */
|
||||
/* Returns 1 if the normal is not within tolerance, but direction is OK */
|
||||
/* Returns 2 if the normal is not within tolerance and backwards */
|
||||
/* Returns 4 if the status is unknown. */
|
||||
|
||||
stl_facet *facet;
|
||||
|
||||
facet = &stl->facet_start[facet_num];
|
||||
|
||||
stl_normal normal;
|
||||
stl_calculate_normal(normal, facet);
|
||||
stl_normalize_vector(normal);
|
||||
stl_normal normal_dif = (normal - facet->normal).cwiseAbs();
|
||||
|
||||
const float eps = 0.001f;
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
/* It is not really necessary to change the values here */
|
||||
/* but just for consistency, I will. */
|
||||
facet->normal = normal;
|
||||
return 0;
|
||||
}
|
||||
|
||||
stl_normal test_norm = facet->normal;
|
||||
stl_normalize_vector(test_norm);
|
||||
normal_dif = (normal - test_norm).cwiseAbs();
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
if(normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
stl->stats.normals_fixed += 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_norm *= -1.f;
|
||||
normal_dif = (normal - test_norm).cwiseAbs();
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
// Facet is backwards.
|
||||
if(normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
stl->stats.normals_fixed += 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if(normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
stl->stats.normals_fixed += 1;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
void stl_fix_normal_values(stl_file *stl) {
|
||||
int i;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl_check_normal_vector(stl, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void stl_reverse_all_facets(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_normal normal;
|
||||
for(int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl_reverse_facet(stl, i);
|
||||
stl_calculate_normal(normal, &stl->facet_start[i]);
|
||||
stl_normalize_vector(normal);
|
||||
stl->facet_start[i].normal = normal;
|
||||
}
|
||||
}
|
||||
264
src/admesh/shared.cpp
Normal file
264
src/admesh/shared.cpp
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
void
|
||||
stl_invalidate_shared_vertices(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
|
||||
if (stl->v_indices != NULL) {
|
||||
free(stl->v_indices);
|
||||
stl->v_indices = NULL;
|
||||
}
|
||||
if (stl->v_shared != NULL) {
|
||||
free(stl->v_shared);
|
||||
stl->v_shared = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_generate_shared_vertices(stl_file *stl) {
|
||||
int i;
|
||||
int j;
|
||||
int first_facet;
|
||||
int direction;
|
||||
int facet_num;
|
||||
int vnot;
|
||||
int next_edge;
|
||||
int pivot_vertex;
|
||||
int next_facet;
|
||||
int reversed;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* make sure this function is idempotent and does not leak memory */
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
|
||||
stl->v_indices = (v_indices_struct*)
|
||||
calloc(stl->stats.number_of_facets, sizeof(v_indices_struct));
|
||||
if(stl->v_indices == NULL) perror("stl_generate_shared_vertices");
|
||||
stl->v_shared = (stl_vertex*)
|
||||
calloc((stl->stats.number_of_facets / 2), sizeof(stl_vertex));
|
||||
if(stl->v_shared == NULL) perror("stl_generate_shared_vertices");
|
||||
stl->stats.shared_malloced = stl->stats.number_of_facets / 2;
|
||||
stl->stats.shared_vertices = 0;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl->v_indices[i].vertex[0] = -1;
|
||||
stl->v_indices[i].vertex[1] = -1;
|
||||
stl->v_indices[i].vertex[2] = -1;
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
first_facet = i;
|
||||
for(j = 0; j < 3; j++) {
|
||||
if(stl->v_indices[i].vertex[j] != -1) {
|
||||
continue;
|
||||
}
|
||||
if(stl->stats.shared_vertices == stl->stats.shared_malloced) {
|
||||
stl->stats.shared_malloced += 1024;
|
||||
stl->v_shared = (stl_vertex*)realloc(stl->v_shared,
|
||||
stl->stats.shared_malloced * sizeof(stl_vertex));
|
||||
if(stl->v_shared == NULL) perror("stl_generate_shared_vertices");
|
||||
}
|
||||
|
||||
stl->v_shared[stl->stats.shared_vertices] =
|
||||
stl->facet_start[i].vertex[j];
|
||||
|
||||
direction = 0;
|
||||
reversed = 0;
|
||||
facet_num = i;
|
||||
vnot = (j + 2) % 3;
|
||||
|
||||
for(;;) {
|
||||
if(vnot > 2) {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
direction = 1;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
direction = 0;
|
||||
}
|
||||
} else {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
}
|
||||
stl->v_indices[facet_num].vertex[pivot_vertex] =
|
||||
stl->stats.shared_vertices;
|
||||
|
||||
next_facet = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||
if(next_facet == -1) {
|
||||
if(reversed) {
|
||||
break;
|
||||
} else {
|
||||
direction = 1;
|
||||
vnot = (j + 1) % 3;
|
||||
reversed = 1;
|
||||
facet_num = first_facet;
|
||||
}
|
||||
} else if(next_facet != first_facet) {
|
||||
vnot = stl->neighbors_start[facet_num].
|
||||
which_vertex_not[next_edge];
|
||||
facet_num = next_facet;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
stl->stats.shared_vertices += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_off(stl_file *stl, char *file) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "OFF\n");
|
||||
fprintf(fp, "%d %d 0\n",
|
||||
stl->stats.shared_vertices, stl->stats.number_of_facets);
|
||||
|
||||
for(i = 0; i < stl->stats.shared_vertices; i++) {
|
||||
fprintf(fp, "\t%f %f %f\n",
|
||||
stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
}
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, "\t3 %d %d %d\n", stl->v_indices[i].vertex[0],
|
||||
stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_vrml(stl_file *stl, char *file) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "#VRML V1.0 ascii\n\n");
|
||||
fprintf(fp, "Separator {\n");
|
||||
fprintf(fp, "\tDEF STLShape ShapeHints {\n");
|
||||
fprintf(fp, "\t\tvertexOrdering COUNTERCLOCKWISE\n");
|
||||
fprintf(fp, "\t\tfaceType CONVEX\n");
|
||||
fprintf(fp, "\t\tshapeType SOLID\n");
|
||||
fprintf(fp, "\t\tcreaseAngle 0.0\n");
|
||||
fprintf(fp, "\t}\n");
|
||||
fprintf(fp, "\tDEF STLModel Separator {\n");
|
||||
fprintf(fp, "\t\tDEF STLColor Material {\n");
|
||||
fprintf(fp, "\t\t\temissiveColor 0.700000 0.700000 0.000000\n");
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t\tDEF STLVertices Coordinate3 {\n");
|
||||
fprintf(fp, "\t\t\tpoint [\n");
|
||||
|
||||
for(i = 0; i < (stl->stats.shared_vertices - 1); i++) {
|
||||
fprintf(fp, "\t\t\t\t%f %f %f,\n",
|
||||
stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
}
|
||||
fprintf(fp, "\t\t\t\t%f %f %f]\n",
|
||||
stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t\tDEF STLTriangles IndexedFaceSet {\n");
|
||||
fprintf(fp, "\t\t\tcoordIndex [\n");
|
||||
|
||||
for(i = 0; i < (stl->stats.number_of_facets - 1); i++) {
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1,\n", stl->v_indices[i].vertex[0],
|
||||
stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]);
|
||||
}
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1]\n", stl->v_indices[i].vertex[0],
|
||||
stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]);
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t}\n");
|
||||
fprintf(fp, "}\n");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void stl_write_obj (stl_file *stl, char *file) {
|
||||
int i;
|
||||
FILE* fp;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == NULL) {
|
||||
char* error_msg = (char*)malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing", file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < stl->stats.shared_vertices; i++) {
|
||||
fprintf(fp, "v %f %f %f\n", stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
}
|
||||
for (i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, "f %d %d %d\n", stl->v_indices[i].vertex[0]+1, stl->v_indices[i].vertex[1]+1, stl->v_indices[i].vertex[2]+1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
215
src/admesh/stl.h
Normal file
215
src/admesh/stl.h
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#ifndef __admesh_stl__
|
||||
#define __admesh_stl__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
// Size of the binary STL header, free form.
|
||||
#define LABEL_SIZE 80
|
||||
// Binary STL, length of the "number of faces" counter.
|
||||
#define NUM_FACET_SIZE 4
|
||||
// Binary STL, sizeof header + number of faces.
|
||||
#define HEADER_SIZE 84
|
||||
#define STL_MIN_FILE_SIZE 284
|
||||
#define ASCII_LINES_PER_FACET 7
|
||||
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_vertex;
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_normal;
|
||||
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
|
||||
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
|
||||
|
||||
typedef struct {
|
||||
stl_normal normal;
|
||||
stl_vertex vertex[3];
|
||||
char extra[2];
|
||||
} stl_facet;
|
||||
#define SIZEOF_STL_FACET 50
|
||||
|
||||
static_assert(offsetof(stl_facet, normal) == 0, "stl_facet.normal has correct offset");
|
||||
static_assert(offsetof(stl_facet, vertex) == 12, "stl_facet.vertex has correct offset");
|
||||
static_assert(offsetof(stl_facet, extra ) == 48, "stl_facet.extra has correct offset");
|
||||
static_assert(sizeof(stl_facet) >= SIZEOF_STL_FACET, "size of stl_facet incorrect");
|
||||
|
||||
typedef enum {binary, ascii, inmemory} stl_type;
|
||||
|
||||
typedef struct {
|
||||
stl_vertex p1;
|
||||
stl_vertex p2;
|
||||
int facet_number;
|
||||
} stl_edge;
|
||||
|
||||
typedef struct stl_hash_edge {
|
||||
// Key of a hash edge: sorted vertices of the edge.
|
||||
unsigned char key[2 * sizeof(stl_vertex)];
|
||||
// Compare two keys.
|
||||
bool operator==(const stl_hash_edge &rhs) { return memcmp(key, rhs.key, sizeof(key)) == 0; }
|
||||
bool operator!=(const stl_hash_edge &rhs) { return ! (*this == rhs); }
|
||||
int hash(int M) const { return ((key[0] / 23 + key[1] / 19 + key[2] / 17 + key[3] /13 + key[4] / 11 + key[5] / 7 ) % M); }
|
||||
// Index of a facet owning this edge.
|
||||
int facet_number;
|
||||
// Index of this edge inside the facet with an index of facet_number.
|
||||
// If this edge is stored backwards, which_edge is increased by 3.
|
||||
int which_edge;
|
||||
struct stl_hash_edge *next;
|
||||
} stl_hash_edge;
|
||||
|
||||
typedef struct {
|
||||
// Index of a neighbor facet.
|
||||
int neighbor[3];
|
||||
// Index of an opposite vertex at the neighbor face.
|
||||
char which_vertex_not[3];
|
||||
} stl_neighbors;
|
||||
|
||||
typedef struct {
|
||||
int vertex[3];
|
||||
} v_indices_struct;
|
||||
|
||||
typedef struct {
|
||||
char header[81];
|
||||
stl_type type;
|
||||
uint32_t number_of_facets;
|
||||
stl_vertex max;
|
||||
stl_vertex min;
|
||||
stl_vertex size;
|
||||
float bounding_diameter;
|
||||
float shortest_edge;
|
||||
float volume;
|
||||
unsigned number_of_blocks;
|
||||
int connected_edges;
|
||||
int connected_facets_1_edge;
|
||||
int connected_facets_2_edge;
|
||||
int connected_facets_3_edge;
|
||||
int facets_w_1_bad_edge;
|
||||
int facets_w_2_bad_edge;
|
||||
int facets_w_3_bad_edge;
|
||||
int original_num_facets;
|
||||
int edges_fixed;
|
||||
int degenerate_facets;
|
||||
int facets_removed;
|
||||
int facets_added;
|
||||
int facets_reversed;
|
||||
int backwards_edges;
|
||||
int normals_fixed;
|
||||
int number_of_parts;
|
||||
int malloced;
|
||||
int freed;
|
||||
int facets_malloced;
|
||||
int collisions;
|
||||
int shared_vertices;
|
||||
int shared_malloced;
|
||||
} stl_stats;
|
||||
|
||||
typedef struct {
|
||||
FILE *fp;
|
||||
stl_facet *facet_start;
|
||||
stl_edge *edge_start;
|
||||
stl_hash_edge **heads;
|
||||
stl_hash_edge *tail;
|
||||
int M;
|
||||
stl_neighbors *neighbors_start;
|
||||
v_indices_struct *v_indices;
|
||||
stl_vertex *v_shared;
|
||||
stl_stats stats;
|
||||
char error;
|
||||
} stl_file;
|
||||
|
||||
|
||||
extern void stl_open(stl_file *stl, const char *file);
|
||||
extern void stl_close(stl_file *stl);
|
||||
extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file);
|
||||
extern void stl_print_edges(stl_file *stl, FILE *file);
|
||||
extern void stl_print_neighbors(stl_file *stl, char *file);
|
||||
extern void stl_put_little_int(FILE *fp, int value_in);
|
||||
extern void stl_put_little_float(FILE *fp, float value_in);
|
||||
extern void stl_write_ascii(stl_file *stl, const char *file, const char *label);
|
||||
extern void stl_write_binary(stl_file *stl, const char *file, const char *label);
|
||||
extern void stl_write_binary_block(stl_file *stl, FILE *fp);
|
||||
extern void stl_check_facets_exact(stl_file *stl);
|
||||
extern void stl_check_facets_nearby(stl_file *stl, float tolerance);
|
||||
extern void stl_remove_unconnected_facets(stl_file *stl);
|
||||
extern void stl_write_vertex(stl_file *stl, int facet, int vertex);
|
||||
extern void stl_write_facet(stl_file *stl, char *label, int facet);
|
||||
extern void stl_write_edge(stl_file *stl, char *label, stl_hash_edge edge);
|
||||
extern void stl_write_neighbor(stl_file *stl, int facet);
|
||||
extern void stl_write_quad_object(stl_file *stl, char *file);
|
||||
extern void stl_verify_neighbors(stl_file *stl);
|
||||
extern void stl_fill_holes(stl_file *stl);
|
||||
extern void stl_fix_normal_directions(stl_file *stl);
|
||||
extern void stl_fix_normal_values(stl_file *stl);
|
||||
extern void stl_reverse_all_facets(stl_file *stl);
|
||||
extern void stl_translate(stl_file *stl, float x, float y, float z);
|
||||
extern void stl_translate_relative(stl_file *stl, float x, float y, float z);
|
||||
extern void stl_scale_versor(stl_file *stl, const stl_vertex &versor);
|
||||
inline void stl_scale(stl_file *stl, float factor) { stl_scale_versor(stl, stl_vertex(factor, factor, factor)); }
|
||||
extern void stl_rotate_x(stl_file *stl, float angle);
|
||||
extern void stl_rotate_y(stl_file *stl, float angle);
|
||||
extern void stl_rotate_z(stl_file *stl, float angle);
|
||||
extern void stl_mirror_xy(stl_file *stl);
|
||||
extern void stl_mirror_yz(stl_file *stl);
|
||||
extern void stl_mirror_xz(stl_file *stl);
|
||||
extern void stl_transform(stl_file *stl, float *trafo3x4);
|
||||
extern void stl_transform(stl_file *stl, const Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign>& t);
|
||||
extern void stl_open_merge(stl_file *stl, char *file);
|
||||
extern void stl_invalidate_shared_vertices(stl_file *stl);
|
||||
extern void stl_generate_shared_vertices(stl_file *stl);
|
||||
extern void stl_write_obj(stl_file *stl, char *file);
|
||||
extern void stl_write_off(stl_file *stl, char *file);
|
||||
extern void stl_write_dxf(stl_file *stl, char *file, char *label);
|
||||
extern void stl_write_vrml(stl_file *stl, char *file);
|
||||
inline void stl_calculate_normal(stl_normal &normal, stl_facet *facet) {
|
||||
normal = (facet->vertex[1] - facet->vertex[0]).cross(facet->vertex[2] - facet->vertex[0]);
|
||||
}
|
||||
inline void stl_normalize_vector(stl_normal &normal) {
|
||||
double length = normal.cast<double>().norm();
|
||||
if (length < 0.000000000001)
|
||||
normal = stl_normal::Zero();
|
||||
else
|
||||
normal *= (1.0 / length);
|
||||
}
|
||||
inline bool stl_vertex_lower(const stl_vertex &a, const stl_vertex &b) {
|
||||
return (a(0) != b(0)) ? (a(0) < b(0)) :
|
||||
((a(1) != b(1)) ? (a(1) < b(1)) : (a(2) < b(2)));
|
||||
}
|
||||
extern void stl_calculate_volume(stl_file *stl);
|
||||
|
||||
extern void stl_repair(stl_file *stl, int fixall_flag, int exact_flag, int tolerance_flag, float tolerance, int increment_flag, float increment, int nearby_flag, int iterations, int remove_unconnected_flag, int fill_holes_flag, int normal_directions_flag, int normal_values_flag, int reverse_all_flag, int verbose_flag);
|
||||
|
||||
extern void stl_initialize(stl_file *stl);
|
||||
extern void stl_count_facets(stl_file *stl, const char *file);
|
||||
extern void stl_allocate(stl_file *stl);
|
||||
extern void stl_read(stl_file *stl, int first_facet, bool first);
|
||||
extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first);
|
||||
extern void stl_reallocate(stl_file *stl);
|
||||
extern void stl_add_facet(stl_file *stl, stl_facet *new_facet);
|
||||
extern void stl_get_size(stl_file *stl);
|
||||
|
||||
extern void stl_clear_error(stl_file *stl);
|
||||
extern int stl_get_error(stl_file *stl);
|
||||
extern void stl_exit_on_error(stl_file *stl);
|
||||
|
||||
#endif
|
||||
433
src/admesh/stl_io.cpp
Normal file
433
src/admesh/stl_io.cpp
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "stl.h"
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
|
||||
#if !defined(SEEK_SET)
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
void
|
||||
stl_print_edges(stl_file *stl, FILE *file) {
|
||||
int i;
|
||||
int edges_allocated;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
edges_allocated = stl->stats.number_of_facets * 3;
|
||||
for(i = 0; i < edges_allocated; i++) {
|
||||
fprintf(file, "%d, %f, %f, %f, %f, %f, %f\n",
|
||||
stl->edge_start[i].facet_number,
|
||||
stl->edge_start[i].p1(0), stl->edge_start[i].p1(1),
|
||||
stl->edge_start[i].p1(2), stl->edge_start[i].p2(0),
|
||||
stl->edge_start[i].p2(1), stl->edge_start[i].p2(2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
stl_stats_out(stl_file *stl, FILE *file, char *input_file) {
|
||||
if (stl->error) return;
|
||||
|
||||
/* this is here for Slic3r, without our config.h
|
||||
it won't use this part of the code anyway */
|
||||
#ifndef VERSION
|
||||
#define VERSION "unknown"
|
||||
#endif
|
||||
fprintf(file, "\n\
|
||||
================= Results produced by ADMesh version " VERSION " ================\n");
|
||||
fprintf(file, "\
|
||||
Input file : %s\n", input_file);
|
||||
if(stl->stats.type == binary) {
|
||||
fprintf(file, "\
|
||||
File type : Binary STL file\n");
|
||||
} else {
|
||||
fprintf(file, "\
|
||||
File type : ASCII STL file\n");
|
||||
}
|
||||
fprintf(file, "\
|
||||
Header : %s\n", stl->stats.header);
|
||||
fprintf(file, "============== Size ==============\n");
|
||||
fprintf(file, "Min X = % f, Max X = % f\n",
|
||||
stl->stats.min(0), stl->stats.max(0));
|
||||
fprintf(file, "Min Y = % f, Max Y = % f\n",
|
||||
stl->stats.min(1), stl->stats.max(1));
|
||||
fprintf(file, "Min Z = % f, Max Z = % f\n",
|
||||
stl->stats.min(2), stl->stats.max(2));
|
||||
|
||||
fprintf(file, "\
|
||||
========= Facet Status ========== Original ============ Final ====\n");
|
||||
fprintf(file, "\
|
||||
Number of facets : %5d %5d\n",
|
||||
stl->stats.original_num_facets, stl->stats.number_of_facets);
|
||||
fprintf(file, "\
|
||||
Facets with 1 disconnected edge : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge, stl->stats.connected_facets_2_edge -
|
||||
stl->stats.connected_facets_3_edge);
|
||||
fprintf(file, "\
|
||||
Facets with 2 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_2_bad_edge, stl->stats.connected_facets_1_edge -
|
||||
stl->stats.connected_facets_2_edge);
|
||||
fprintf(file, "\
|
||||
Facets with 3 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets -
|
||||
stl->stats.connected_facets_1_edge);
|
||||
fprintf(file, "\
|
||||
Total disconnected facets : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge + stl->stats.facets_w_2_bad_edge +
|
||||
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets -
|
||||
stl->stats.connected_facets_3_edge);
|
||||
|
||||
fprintf(file,
|
||||
"=== Processing Statistics === ===== Other Statistics =====\n");
|
||||
fprintf(file, "\
|
||||
Number of parts : %5d Volume : % f\n",
|
||||
stl->stats.number_of_parts, stl->stats.volume);
|
||||
fprintf(file, "\
|
||||
Degenerate facets : %5d\n", stl->stats.degenerate_facets);
|
||||
fprintf(file, "\
|
||||
Edges fixed : %5d\n", stl->stats.edges_fixed);
|
||||
fprintf(file, "\
|
||||
Facets removed : %5d\n", stl->stats.facets_removed);
|
||||
fprintf(file, "\
|
||||
Facets added : %5d\n", stl->stats.facets_added);
|
||||
fprintf(file, "\
|
||||
Facets reversed : %5d\n", stl->stats.facets_reversed);
|
||||
fprintf(file, "\
|
||||
Backwards edges : %5d\n", stl->stats.backwards_edges);
|
||||
fprintf(file, "\
|
||||
Normals fixed : %5d\n", stl->stats.normals_fixed);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_ascii(stl_file *stl, const char *file, const char *label) {
|
||||
int i;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "solid %s\n", label);
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, " facet normal % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].normal(0), stl->facet_start[i].normal(1),
|
||||
stl->facet_start[i].normal(2));
|
||||
fprintf(fp, " outer loop\n");
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
|
||||
stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
|
||||
stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, " endloop\n");
|
||||
fprintf(fp, " endfacet\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "endsolid %s\n", label);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
stl_print_neighbors(stl_file *stl, char *file) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_print_neighbors: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
|
||||
i,
|
||||
stl->neighbors_start[i].neighbor[0],
|
||||
(int)stl->neighbors_start[i].which_vertex_not[0],
|
||||
stl->neighbors_start[i].neighbor[1],
|
||||
(int)stl->neighbors_start[i].which_vertex_not[1],
|
||||
stl->neighbors_start[i].neighbor[2],
|
||||
(int)stl->neighbors_start[i].which_vertex_not[2]);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
// Swap a buffer of 32bit data from little endian to big endian and vice versa.
|
||||
void stl_internal_reverse_quads(char *buf, size_t cnt)
|
||||
{
|
||||
for (size_t i = 0; i < cnt; i += 4) {
|
||||
std::swap(buf[i], buf[i+3]);
|
||||
std::swap(buf[i+1], buf[i+2]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
stl_write_binary(stl_file *stl, const char *file, const char *label) {
|
||||
FILE *fp;
|
||||
int i;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "wb");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_binary: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "%s", label);
|
||||
for(i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
|
||||
|
||||
fseek(fp, LABEL_SIZE, SEEK_SET);
|
||||
#ifdef BOOST_LITTLE_ENDIAN
|
||||
fwrite(&stl->stats.number_of_facets, 4, 1, fp);
|
||||
for (i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
fwrite(stl->facet_start + i, SIZEOF_STL_FACET, 1, fp);
|
||||
#else /* BOOST_LITTLE_ENDIAN */
|
||||
char buffer[50];
|
||||
// Convert the number of facets to little endian.
|
||||
memcpy(buffer, &stl->stats.number_of_facets, 4);
|
||||
stl_internal_reverse_quads(buffer, 4);
|
||||
fwrite(buffer, 4, 1, fp);
|
||||
for (i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
memcpy(buffer, stl->facet_start + i, 50);
|
||||
// Convert to little endian.
|
||||
stl_internal_reverse_quads(buffer, 48);
|
||||
fwrite(buffer, SIZEOF_STL_FACET, 1, fp);
|
||||
}
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_vertex(stl_file *stl, int facet, int vertex) {
|
||||
if (stl->error) return;
|
||||
printf(" vertex %d/%d % .8E % .8E % .8E\n", vertex, facet,
|
||||
stl->facet_start[facet].vertex[vertex](0),
|
||||
stl->facet_start[facet].vertex[vertex](1),
|
||||
stl->facet_start[facet].vertex[vertex](2));
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_facet(stl_file *stl, char *label, int facet) {
|
||||
if (stl->error) return;
|
||||
printf("facet (%d)/ %s\n", facet, label);
|
||||
stl_write_vertex(stl, facet, 0);
|
||||
stl_write_vertex(stl, facet, 1);
|
||||
stl_write_vertex(stl, facet, 2);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_edge(stl_file *stl, char *label, stl_hash_edge edge) {
|
||||
if (stl->error) return;
|
||||
printf("edge (%d)/(%d) %s\n", edge.facet_number, edge.which_edge, label);
|
||||
if(edge.which_edge < 3) {
|
||||
stl_write_vertex(stl, edge.facet_number, edge.which_edge % 3);
|
||||
stl_write_vertex(stl, edge.facet_number, (edge.which_edge + 1) % 3);
|
||||
} else {
|
||||
stl_write_vertex(stl, edge.facet_number, (edge.which_edge + 1) % 3);
|
||||
stl_write_vertex(stl, edge.facet_number, edge.which_edge % 3);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_neighbor(stl_file *stl, int facet) {
|
||||
if (stl->error) return;
|
||||
printf("Neighbors %d: %d, %d, %d ; %d, %d, %d\n", facet,
|
||||
stl->neighbors_start[facet].neighbor[0],
|
||||
stl->neighbors_start[facet].neighbor[1],
|
||||
stl->neighbors_start[facet].neighbor[2],
|
||||
stl->neighbors_start[facet].which_vertex_not[0],
|
||||
stl->neighbors_start[facet].which_vertex_not[1],
|
||||
stl->neighbors_start[facet].which_vertex_not[2]);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_quad_object(stl_file *stl, char *file) {
|
||||
FILE *fp;
|
||||
int i;
|
||||
int j;
|
||||
char *error_msg;
|
||||
stl_vertex connect_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_1_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_2_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_3_color = stl_vertex::Zero();
|
||||
stl_vertex color;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_quad_object: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "CQUAD\n");
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
j = ((stl->neighbors_start[i].neighbor[0] == -1) +
|
||||
(stl->neighbors_start[i].neighbor[1] == -1) +
|
||||
(stl->neighbors_start[i].neighbor[2] == -1));
|
||||
if(j == 0) {
|
||||
color = connect_color;
|
||||
} else if(j == 1) {
|
||||
color = uncon_1_color;
|
||||
} else if(j == 2) {
|
||||
color = uncon_2_color;
|
||||
} else {
|
||||
color = uncon_3_color;
|
||||
}
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[0](0),
|
||||
stl->facet_start[i].vertex[0](1),
|
||||
stl->facet_start[i].vertex[0](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[1](0),
|
||||
stl->facet_start[i].vertex[1](1),
|
||||
stl->facet_start[i].vertex[1](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[2](0),
|
||||
stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[2](0),
|
||||
stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_dxf(stl_file *stl, char *file, char *label) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, "999\n%s\n", label);
|
||||
fprintf(fp, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n");
|
||||
fprintf(fp, "0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n70\n1\n\
|
||||
0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
|
||||
fprintf(fp, "0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n");
|
||||
|
||||
fprintf(fp, "0\nSECTION\n2\nENTITIES\n");
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, "0\n3DFACE\n8\n0\n");
|
||||
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n",
|
||||
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
|
||||
stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n",
|
||||
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
|
||||
stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n",
|
||||
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n",
|
||||
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2));
|
||||
}
|
||||
|
||||
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
stl_clear_error(stl_file *stl) {
|
||||
stl->error = 0;
|
||||
}
|
||||
|
||||
void
|
||||
stl_exit_on_error(stl_file *stl) {
|
||||
if (!stl->error) return;
|
||||
stl->error = 0;
|
||||
stl_close(stl);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
stl_get_error(stl_file *stl) {
|
||||
return stl->error;
|
||||
}
|
||||
382
src/admesh/stlinit.cpp
Normal file
382
src/admesh/stlinit.cpp
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#error "SEEK_SET not defined"
|
||||
#endif
|
||||
|
||||
void
|
||||
stl_open(stl_file *stl, const char *file) {
|
||||
stl_initialize(stl);
|
||||
stl_count_facets(stl, file);
|
||||
stl_allocate(stl);
|
||||
stl_read(stl, 0, true);
|
||||
if (!stl->error) fclose(stl->fp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
stl_initialize(stl_file *stl) {
|
||||
memset(stl, 0, sizeof(stl_file));
|
||||
stl->stats.volume = -1.0;
|
||||
}
|
||||
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
extern void stl_internal_reverse_quads(char *buf, size_t cnt);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
|
||||
void
|
||||
stl_count_facets(stl_file *stl, const char *file) {
|
||||
long file_size;
|
||||
uint32_t header_num_facets;
|
||||
uint32_t num_facets;
|
||||
int i;
|
||||
size_t s;
|
||||
unsigned char chtest[128];
|
||||
int num_lines = 1;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file in binary mode first */
|
||||
stl->fp = boost::nowide::fopen(file, "rb");
|
||||
if(stl->fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
/* Find size of file */
|
||||
fseek(stl->fp, 0, SEEK_END);
|
||||
file_size = ftell(stl->fp);
|
||||
|
||||
/* Check for binary or ASCII file */
|
||||
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
|
||||
if (!fread(chtest, sizeof(chtest), 1, stl->fp)) {
|
||||
perror("The input is an empty file");
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
stl->stats.type = ascii;
|
||||
for(s = 0; s < sizeof(chtest); s++) {
|
||||
if(chtest[s] > 127) {
|
||||
stl->stats.type = binary;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rewind(stl->fp);
|
||||
|
||||
/* Get the header and the number of facets in the .STL file */
|
||||
/* If the .STL file is binary, then do the following */
|
||||
if(stl->stats.type == binary) {
|
||||
/* Test if the STL file has the right size */
|
||||
if(((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0)
|
||||
|| (file_size < STL_MIN_FILE_SIZE)) {
|
||||
fprintf(stderr, "The file %s has the wrong size.\n", file);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
|
||||
|
||||
/* Read the header */
|
||||
if (fread(stl->stats.header, LABEL_SIZE, 1, stl->fp) > 79) {
|
||||
stl->stats.header[80] = '\0';
|
||||
}
|
||||
|
||||
/* Read the int following the header. This should contain # of facets */
|
||||
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, stl->fp);
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
// Convert from little endian to big endian.
|
||||
stl_internal_reverse_quads((char*)&header_num_facets, 4);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
if (! header_num_faces_read || num_facets != header_num_facets) {
|
||||
fprintf(stderr,
|
||||
"Warning: File size doesn't match number of facets in the header\n");
|
||||
}
|
||||
}
|
||||
/* Otherwise, if the .STL file is ASCII, then do the following */
|
||||
else {
|
||||
/* Reopen the file in text mode (for getting correct newlines on Windows) */
|
||||
// fix to silence a warning about unused return value.
|
||||
// obviously if it fails we have problems....
|
||||
stl->fp = boost::nowide::freopen(file, "r", stl->fp);
|
||||
|
||||
// do another null check to be safe
|
||||
if(stl->fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the number of facets */
|
||||
char linebuf[100];
|
||||
while (fgets(linebuf, 100, stl->fp) != NULL) {
|
||||
/* don't count short lines */
|
||||
if (strlen(linebuf) <= 4) continue;
|
||||
|
||||
/* skip solid/endsolid lines as broken STL file generators may put several of them */
|
||||
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0) continue;
|
||||
|
||||
++num_lines;
|
||||
}
|
||||
|
||||
rewind(stl->fp);
|
||||
|
||||
/* Get the header */
|
||||
for(i = 0;
|
||||
(i < 80) && (stl->stats.header[i] = getc(stl->fp)) != '\n'; i++);
|
||||
stl->stats.header[i] = '\0'; /* Lose the '\n' */
|
||||
stl->stats.header[80] = '\0';
|
||||
|
||||
num_facets = num_lines / ASCII_LINES_PER_FACET;
|
||||
}
|
||||
stl->stats.number_of_facets += num_facets;
|
||||
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
||||
}
|
||||
|
||||
void
|
||||
stl_allocate(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
|
||||
/* Allocate memory for the entire .STL file */
|
||||
stl->facet_start = (stl_facet*)calloc(stl->stats.number_of_facets,
|
||||
sizeof(stl_facet));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
stl->stats.facets_malloced = stl->stats.number_of_facets;
|
||||
|
||||
/* Allocate memory for the neighbors list */
|
||||
stl->neighbors_start = (stl_neighbors*)
|
||||
calloc(stl->stats.number_of_facets, sizeof(stl_neighbors));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
}
|
||||
|
||||
void
|
||||
stl_open_merge(stl_file *stl, char *file_to_merge) {
|
||||
int num_facets_so_far;
|
||||
stl_type origStlType;
|
||||
FILE *origFp;
|
||||
stl_file stl_to_merge;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Record how many facets we have so far from the first file. We will start putting
|
||||
facets in the next position. Since we're 0-indexed, it'l be the same position. */
|
||||
num_facets_so_far = stl->stats.number_of_facets;
|
||||
|
||||
/* Record the file type we started with: */
|
||||
origStlType=stl->stats.type;
|
||||
/* Record the file pointer too: */
|
||||
origFp=stl->fp;
|
||||
|
||||
/* Initialize the sturucture with zero stats, header info and sizes: */
|
||||
stl_initialize(&stl_to_merge);
|
||||
stl_count_facets(&stl_to_merge, file_to_merge);
|
||||
|
||||
/* Copy what we need to into stl so that we can read the file_to_merge directly into it
|
||||
using stl_read: Save the rest of the valuable info: */
|
||||
stl->stats.type=stl_to_merge.stats.type;
|
||||
stl->fp=stl_to_merge.fp;
|
||||
|
||||
/* Add the number of facets we already have in stl with what we we found in stl_to_merge but
|
||||
haven't read yet. */
|
||||
stl->stats.number_of_facets=num_facets_so_far+stl_to_merge.stats.number_of_facets;
|
||||
|
||||
/* Allocate enough room for stl->stats.number_of_facets facets and neighbors: */
|
||||
stl_reallocate(stl);
|
||||
|
||||
/* Read the file to merge directly into stl, adding it to what we have already.
|
||||
Start at num_facets_so_far, the index to the first unused facet. Also say
|
||||
that this isn't our first time so we should augment stats like min and max
|
||||
instead of erasing them. */
|
||||
stl_read(stl, num_facets_so_far, false);
|
||||
|
||||
/* Restore the stl information we overwrote (for stl_read) so that it still accurately
|
||||
reflects the subject part: */
|
||||
stl->stats.type=origStlType;
|
||||
stl->fp=origFp;
|
||||
}
|
||||
|
||||
extern void
|
||||
stl_reallocate(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
/* Reallocate more memory for the .STL file(s) */
|
||||
stl->facet_start = (stl_facet*)realloc(stl->facet_start, stl->stats.number_of_facets *
|
||||
sizeof(stl_facet));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
stl->stats.facets_malloced = stl->stats.number_of_facets;
|
||||
|
||||
/* Reallocate more memory for the neighbors list */
|
||||
stl->neighbors_start = (stl_neighbors*)
|
||||
realloc(stl->neighbors_start, stl->stats.number_of_facets *
|
||||
sizeof(stl_neighbors));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
}
|
||||
|
||||
|
||||
/* Reads the contents of the file pointed to by stl->fp into the stl structure,
|
||||
starting at facet first_facet. The second argument says if it's our first
|
||||
time running this for the stl and therefore we should reset our max and min stats. */
|
||||
void stl_read(stl_file *stl, int first_facet, bool first) {
|
||||
stl_facet facet;
|
||||
int i;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
if(stl->stats.type == binary) {
|
||||
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
|
||||
} else {
|
||||
rewind(stl->fp);
|
||||
}
|
||||
|
||||
char normal_buf[3][32];
|
||||
for(i = first_facet; i < stl->stats.number_of_facets; i++) {
|
||||
if(stl->stats.type == binary)
|
||||
/* Read a single facet from a binary .STL file */
|
||||
{
|
||||
/* we assume little-endian architecture! */
|
||||
if (fread(&facet, 1, SIZEOF_STL_FACET, stl->fp) != SIZEOF_STL_FACET) {
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
// Convert the loaded little endian data to big endian.
|
||||
stl_internal_reverse_quads((char*)&facet, 48);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
} else
|
||||
/* Read a single facet from an ASCII .STL file */
|
||||
{
|
||||
// skip solid/endsolid
|
||||
// (in this order, otherwise it won't work when they are paired in the middle of a file)
|
||||
fscanf(stl->fp, "endsolid%*[^\n]\n");
|
||||
fscanf(stl->fp, "solid%*[^\n]\n"); // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
|
||||
// Leading space in the fscanf format skips all leading white spaces including numerous new lines and tabs.
|
||||
int res_normal = fscanf(stl->fp, " facet normal %31s %31s %31s", normal_buf[0], normal_buf[1], normal_buf[2]);
|
||||
assert(res_normal == 3);
|
||||
int res_outer_loop = fscanf(stl->fp, " outer loop");
|
||||
assert(res_outer_loop == 0);
|
||||
int res_vertex1 = fscanf(stl->fp, " vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
|
||||
assert(res_vertex1 == 3);
|
||||
int res_vertex2 = fscanf(stl->fp, " vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
|
||||
assert(res_vertex2 == 3);
|
||||
int res_vertex3 = fscanf(stl->fp, " vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
|
||||
assert(res_vertex3 == 3);
|
||||
int res_endloop = fscanf(stl->fp, " endloop");
|
||||
assert(res_endloop == 0);
|
||||
// There is a leading and trailing white space around endfacet to eat up all leading and trailing white spaces including numerous tabs and new lines.
|
||||
int res_endfacet = fscanf(stl->fp, " endfacet ");
|
||||
if (res_normal != 3 || res_outer_loop != 0 || res_vertex1 != 3 || res_vertex2 != 3 || res_vertex3 != 3 || res_endloop != 0 || res_endfacet != 0) {
|
||||
perror("Something is syntactically very wrong with this ASCII STL!");
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// The facet normal has been parsed as a single string as to workaround for not a numbers in the normal definition.
|
||||
if (sscanf(normal_buf[0], "%f", &facet.normal(0)) != 1 ||
|
||||
sscanf(normal_buf[1], "%f", &facet.normal(1)) != 1 ||
|
||||
sscanf(normal_buf[2], "%f", &facet.normal(2)) != 1) {
|
||||
// Normal was mangled. Maybe denormals or "not a number" were stored?
|
||||
// Just reset the normal and silently ignore it.
|
||||
memset(&facet.normal, 0, sizeof(facet.normal));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Report close to zero vertex coordinates. Due to the nature of the floating point numbers,
|
||||
// close to zero values may be represented with singificantly higher precision than the rest of the vertices.
|
||||
// It may be worth to round these numbers to zero during loading to reduce the number of errors reported
|
||||
// during the STL import.
|
||||
for (size_t j = 0; j < 3; ++ j) {
|
||||
if (facet.vertex[j](0) > -1e-12f && facet.vertex[j](0) < 1e-12f)
|
||||
printf("stl_read: facet %d(0) = %e\r\n", j, facet.vertex[j](0));
|
||||
if (facet.vertex[j](1) > -1e-12f && facet.vertex[j](1) < 1e-12f)
|
||||
printf("stl_read: facet %d(1) = %e\r\n", j, facet.vertex[j](1));
|
||||
if (facet.vertex[j](2) > -1e-12f && facet.vertex[j](2) < 1e-12f)
|
||||
printf("stl_read: facet %d(2) = %e\r\n", j, facet.vertex[j](2));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the facet into memory. */
|
||||
stl->facet_start[i] = facet;
|
||||
stl_facet_stats(stl, facet, first);
|
||||
}
|
||||
stl->stats.size = stl->stats.max - stl->stats.min;
|
||||
stl->stats.bounding_diameter = stl->stats.size.norm();
|
||||
}
|
||||
|
||||
void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
// While we are going through all of the facets, let's find the
|
||||
// maximum and minimum values for x, y, and z
|
||||
|
||||
if (first) {
|
||||
// Initialize the max and min values the first time through
|
||||
stl->stats.min = facet.vertex[0];
|
||||
stl->stats.max = facet.vertex[0];
|
||||
stl_vertex diff = (facet.vertex[1] - facet.vertex[0]).cwiseAbs();
|
||||
stl->stats.shortest_edge = std::max(diff(0), std::max(diff(1), diff(2)));
|
||||
first = false;
|
||||
}
|
||||
|
||||
// Now find the max and min values.
|
||||
for (size_t i = 0; i < 3; ++ i) {
|
||||
stl->stats.min = stl->stats.min.cwiseMin(facet.vertex[i]);
|
||||
stl->stats.max = stl->stats.max.cwiseMax(facet.vertex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_close(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
|
||||
if(stl->neighbors_start != NULL)
|
||||
free(stl->neighbors_start);
|
||||
if(stl->facet_start != NULL)
|
||||
free(stl->facet_start);
|
||||
if(stl->v_indices != NULL)
|
||||
free(stl->v_indices);
|
||||
if(stl->v_shared != NULL)
|
||||
free(stl->v_shared);
|
||||
}
|
||||
|
||||
518
src/admesh/util.cpp
Normal file
518
src/admesh/util.cpp
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
static void stl_rotate(float *x, float *y, const double c, const double s);
|
||||
static float get_area(stl_facet *facet);
|
||||
static float get_volume(stl_file *stl);
|
||||
|
||||
|
||||
void
|
||||
stl_verify_neighbors(stl_file *stl) {
|
||||
int i;
|
||||
int j;
|
||||
stl_edge edge_a;
|
||||
stl_edge edge_b;
|
||||
int neighbor;
|
||||
int vnot;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
stl->stats.backwards_edges = 0;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
edge_a.p1 = stl->facet_start[i].vertex[j];
|
||||
edge_a.p2 = stl->facet_start[i].vertex[(j + 1) % 3];
|
||||
neighbor = stl->neighbors_start[i].neighbor[j];
|
||||
vnot = stl->neighbors_start[i].which_vertex_not[j];
|
||||
|
||||
if(neighbor == -1)
|
||||
continue; /* this edge has no neighbor... Continue. */
|
||||
if(vnot < 3) {
|
||||
edge_b.p1 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
|
||||
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 1) % 3];
|
||||
} else {
|
||||
stl->stats.backwards_edges += 1;
|
||||
edge_b.p1 = stl->facet_start[neighbor].vertex[(vnot + 1) % 3];
|
||||
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
|
||||
}
|
||||
if (edge_a.p1 != edge_b.p1 || edge_a.p2 != edge_b.p2) {
|
||||
/* These edges should match but they don't. Print results. */
|
||||
printf("edge %d of facet %d doesn't match edge %d of facet %d\n",
|
||||
j, i, vnot + 1, neighbor);
|
||||
stl_write_facet(stl, (char*)"first facet", i);
|
||||
stl_write_facet(stl, (char*)"second facet", neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stl_translate(stl_file *stl, float x, float y, float z)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_vertex new_min(x, y, z);
|
||||
stl_vertex shift = new_min - stl->stats.min;
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j] += shift;
|
||||
stl->stats.min = new_min;
|
||||
stl->stats.max += shift;
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
}
|
||||
|
||||
/* Translates the stl by x,y,z, relatively from wherever it is currently */
|
||||
void stl_translate_relative(stl_file *stl, float x, float y, float z)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_vertex shift(x, y, z);
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j] += shift;
|
||||
stl->stats.min += shift;
|
||||
stl->stats.max += shift;
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
}
|
||||
|
||||
void stl_scale_versor(stl_file *stl, const stl_vertex &versor)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
// Scale extents.
|
||||
auto s = versor.array();
|
||||
stl->stats.min.array() *= s;
|
||||
stl->stats.max.array() *= s;
|
||||
// Scale size.
|
||||
stl->stats.size.array() *= s;
|
||||
// Scale volume.
|
||||
if (stl->stats.volume > 0.0)
|
||||
stl->stats.volume *= versor(0) * versor(1) * versor(2);
|
||||
// Scale the mesh.
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j].array() *= s;
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
}
|
||||
|
||||
static void calculate_normals(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_normal normal;
|
||||
for(uint32_t i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl_calculate_normal(normal, &stl->facet_start[i]);
|
||||
stl_normalize_vector(normal);
|
||||
stl->facet_start[i].normal = normal;
|
||||
}
|
||||
}
|
||||
|
||||
void stl_transform(stl_file *stl, float *trafo3x4) {
|
||||
int i_face, i_vertex;
|
||||
if (stl->error)
|
||||
return;
|
||||
for (i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) {
|
||||
stl_vertex *vertices = stl->facet_start[i_face].vertex;
|
||||
for (i_vertex = 0; i_vertex < 3; ++ i_vertex) {
|
||||
stl_vertex &v_dst = vertices[i_vertex];
|
||||
stl_vertex v_src = v_dst;
|
||||
v_dst(0) = trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2) + trafo3x4[3];
|
||||
v_dst(1) = trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7];
|
||||
v_dst(2) = trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11];
|
||||
}
|
||||
}
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void stl_transform(stl_file *stl, const Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign>& t)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
unsigned int vertices_count = 3 * (unsigned int)stl->stats.number_of_facets;
|
||||
if (vertices_count == 0)
|
||||
return;
|
||||
|
||||
Eigen::MatrixXf src_vertices(3, vertices_count);
|
||||
stl_facet* facet_ptr = stl->facet_start;
|
||||
unsigned int v_id = 0;
|
||||
while (facet_ptr < stl->facet_start + stl->stats.number_of_facets)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
::memcpy((void*)src_vertices.col(v_id).data(), (const void*)&facet_ptr->vertex[i], 3 * sizeof(float));
|
||||
++v_id;
|
||||
}
|
||||
facet_ptr += 1;
|
||||
}
|
||||
|
||||
Eigen::MatrixXf dst_vertices(3, vertices_count);
|
||||
dst_vertices = t * src_vertices.colwise().homogeneous();
|
||||
|
||||
facet_ptr = stl->facet_start;
|
||||
v_id = 0;
|
||||
while (facet_ptr < stl->facet_start + stl->stats.number_of_facets)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
::memcpy((void*)&facet_ptr->vertex[i], (const void*)dst_vertices.col(v_id).data(), 3 * sizeof(float));
|
||||
++v_id;
|
||||
}
|
||||
facet_ptr += 1;
|
||||
}
|
||||
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void
|
||||
stl_rotate_x(stl_file *stl, float angle) {
|
||||
int i;
|
||||
int j;
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
stl_rotate(&stl->facet_start[i].vertex[j](1),
|
||||
&stl->facet_start[i].vertex[j](2), c, s);
|
||||
}
|
||||
}
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void
|
||||
stl_rotate_y(stl_file *stl, float angle) {
|
||||
int i;
|
||||
int j;
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
stl_rotate(&stl->facet_start[i].vertex[j](2),
|
||||
&stl->facet_start[i].vertex[j](0), c, s);
|
||||
}
|
||||
}
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void
|
||||
stl_rotate_z(stl_file *stl, float angle) {
|
||||
int i;
|
||||
int j;
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
stl_rotate(&stl->facet_start[i].vertex[j](0),
|
||||
&stl->facet_start[i].vertex[j](1), c, s);
|
||||
}
|
||||
}
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
stl_rotate(float *x, float *y, const double c, const double s) {
|
||||
double xold = *x;
|
||||
double yold = *y;
|
||||
*x = float(c * xold - s * yold);
|
||||
*y = float(s * xold + c * yold);
|
||||
}
|
||||
|
||||
void stl_get_size(stl_file *stl)
|
||||
{
|
||||
if (stl->error || stl->stats.number_of_facets == 0)
|
||||
return;
|
||||
stl->stats.min = stl->facet_start[0].vertex[0];
|
||||
stl->stats.max = stl->stats.min;
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
const stl_facet &face = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
stl->stats.min = stl->stats.min.cwiseMin(face.vertex[j]);
|
||||
stl->stats.max = stl->stats.max.cwiseMax(face.vertex[j]);
|
||||
}
|
||||
}
|
||||
stl->stats.size = stl->stats.max - stl->stats.min;
|
||||
stl->stats.bounding_diameter = stl->stats.size.norm();
|
||||
}
|
||||
|
||||
void stl_mirror_xy(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(int j = 0; j < 3; j++) {
|
||||
stl->facet_start[i].vertex[j](2) *= -1.0;
|
||||
}
|
||||
}
|
||||
float temp_size = stl->stats.min(2);
|
||||
stl->stats.min(2) = stl->stats.max(2);
|
||||
stl->stats.max(2) = temp_size;
|
||||
stl->stats.min(2) *= -1.0;
|
||||
stl->stats.max(2) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; /* for not altering stats */
|
||||
}
|
||||
|
||||
void stl_mirror_yz(stl_file *stl)
|
||||
{
|
||||
if (stl->error) return;
|
||||
|
||||
for (int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
stl->facet_start[i].vertex[j](0) *= -1.0;
|
||||
}
|
||||
}
|
||||
float temp_size = stl->stats.min(0);
|
||||
stl->stats.min(0) = stl->stats.max(0);
|
||||
stl->stats.max(0) = temp_size;
|
||||
stl->stats.min(0) *= -1.0;
|
||||
stl->stats.max(0) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; /* for not altering stats */
|
||||
}
|
||||
|
||||
void stl_mirror_xz(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
stl->facet_start[i].vertex[j](1) *= -1.0;
|
||||
}
|
||||
}
|
||||
float temp_size = stl->stats.min(1);
|
||||
stl->stats.min(1) = stl->stats.max(1);
|
||||
stl->stats.max(1) = temp_size;
|
||||
stl->stats.min(1) *= -1.0;
|
||||
stl->stats.max(1) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; /* for not altering stats */
|
||||
}
|
||||
|
||||
static float get_volume(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return 0;
|
||||
|
||||
// Choose a point, any point as the reference.
|
||||
stl_vertex p0 = stl->facet_start[0].vertex[0];
|
||||
float volume = 0.f;
|
||||
for(uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
// Do dot product to get distance from point to plane.
|
||||
float height = stl->facet_start[i].normal.dot(stl->facet_start[i].vertex[0] - p0);
|
||||
float area = get_area(&stl->facet_start[i]);
|
||||
volume += (area * height) / 3.0f;
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
void stl_calculate_volume(stl_file *stl)
|
||||
{
|
||||
if (stl->error) return;
|
||||
stl->stats.volume = get_volume(stl);
|
||||
if(stl->stats.volume < 0.0) {
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.volume = -stl->stats.volume;
|
||||
}
|
||||
}
|
||||
|
||||
static float get_area(stl_facet *facet)
|
||||
{
|
||||
/* cast to double before calculating cross product because large coordinates
|
||||
can result in overflowing product
|
||||
(bad area is responsible for bad volume and bad facets reversal) */
|
||||
double cross[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cross[i][0]=(((double)facet->vertex[i](1) * (double)facet->vertex[(i + 1) % 3](2)) -
|
||||
((double)facet->vertex[i](2) * (double)facet->vertex[(i + 1) % 3](1)));
|
||||
cross[i][1]=(((double)facet->vertex[i](2) * (double)facet->vertex[(i + 1) % 3](0)) -
|
||||
((double)facet->vertex[i](0) * (double)facet->vertex[(i + 1) % 3](2)));
|
||||
cross[i][2]=(((double)facet->vertex[i](0) * (double)facet->vertex[(i + 1) % 3](1)) -
|
||||
((double)facet->vertex[i](1) * (double)facet->vertex[(i + 1) % 3](0)));
|
||||
}
|
||||
|
||||
stl_normal sum;
|
||||
sum(0) = cross[0][0] + cross[1][0] + cross[2][0];
|
||||
sum(1) = cross[0][1] + cross[1][1] + cross[2][1];
|
||||
sum(2) = cross[0][2] + cross[1][2] + cross[2][2];
|
||||
|
||||
// This should already be done. But just in case, let's do it again.
|
||||
//FIXME this is questionable. the "sum" normal should be accurate, while the normal "n" may be calculated with a low accuracy.
|
||||
stl_normal n;
|
||||
stl_calculate_normal(n, facet);
|
||||
stl_normalize_vector(n);
|
||||
return 0.5f * n.dot(sum);
|
||||
}
|
||||
|
||||
void stl_repair(stl_file *stl,
|
||||
int fixall_flag,
|
||||
int exact_flag,
|
||||
int tolerance_flag,
|
||||
float tolerance,
|
||||
int increment_flag,
|
||||
float increment,
|
||||
int nearby_flag,
|
||||
int iterations,
|
||||
int remove_unconnected_flag,
|
||||
int fill_holes_flag,
|
||||
int normal_directions_flag,
|
||||
int normal_values_flag,
|
||||
int reverse_all_flag,
|
||||
int verbose_flag) {
|
||||
|
||||
int i;
|
||||
int last_edges_fixed = 0;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
if(exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag
|
||||
|| fill_holes_flag || normal_directions_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking exact...\n");
|
||||
exact_flag = 1;
|
||||
stl_check_facets_exact(stl);
|
||||
stl->stats.facets_w_1_bad_edge =
|
||||
(stl->stats.connected_facets_2_edge -
|
||||
stl->stats.connected_facets_3_edge);
|
||||
stl->stats.facets_w_2_bad_edge =
|
||||
(stl->stats.connected_facets_1_edge -
|
||||
stl->stats.connected_facets_2_edge);
|
||||
stl->stats.facets_w_3_bad_edge =
|
||||
(stl->stats.number_of_facets -
|
||||
stl->stats.connected_facets_1_edge);
|
||||
}
|
||||
|
||||
if(nearby_flag || fixall_flag) {
|
||||
if(!tolerance_flag) {
|
||||
tolerance = stl->stats.shortest_edge;
|
||||
}
|
||||
if(!increment_flag) {
|
||||
increment = stl->stats.bounding_diameter / 10000.0;
|
||||
}
|
||||
|
||||
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
for(i = 0; i < iterations; i++) {
|
||||
if(stl->stats.connected_facets_3_edge <
|
||||
stl->stats.number_of_facets) {
|
||||
if (verbose_flag)
|
||||
printf("\
|
||||
Checking nearby. Tolerance= %f Iteration=%d of %d...",
|
||||
tolerance, i + 1, iterations);
|
||||
stl_check_facets_nearby(stl, tolerance);
|
||||
if (verbose_flag)
|
||||
printf(" Fixed %d edges.\n",
|
||||
stl->stats.edges_fixed - last_edges_fixed);
|
||||
last_edges_fixed = stl->stats.edges_fixed;
|
||||
tolerance += increment;
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
printf("\
|
||||
All facets connected. No further nearby check necessary.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
printf("All facets connected. No nearby check necessary.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(remove_unconnected_flag || fixall_flag || fill_holes_flag) {
|
||||
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (verbose_flag)
|
||||
printf("Removing unconnected facets...\n");
|
||||
stl_remove_unconnected_facets(stl);
|
||||
} else
|
||||
if (verbose_flag)
|
||||
printf("No unconnected need to be removed.\n");
|
||||
}
|
||||
|
||||
if(fill_holes_flag || fixall_flag) {
|
||||
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (verbose_flag)
|
||||
printf("Filling holes...\n");
|
||||
stl_fill_holes(stl);
|
||||
} else
|
||||
if (verbose_flag)
|
||||
printf("No holes need to be filled.\n");
|
||||
}
|
||||
|
||||
if(reverse_all_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Reversing all facets...\n");
|
||||
stl_reverse_all_facets(stl);
|
||||
}
|
||||
|
||||
if(normal_directions_flag || fixall_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking normal directions...\n");
|
||||
stl_fix_normal_directions(stl);
|
||||
}
|
||||
|
||||
if(normal_values_flag || fixall_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking normal values...\n");
|
||||
stl_fix_normal_values(stl);
|
||||
}
|
||||
|
||||
/* Always calculate the volume. It shouldn't take too long */
|
||||
if (verbose_flag)
|
||||
printf("Calculating volume...\n");
|
||||
stl_calculate_volume(stl);
|
||||
|
||||
if(exact_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Verifying neighbors...\n");
|
||||
stl_verify_neighbors(stl);
|
||||
}
|
||||
}
|
||||
2
src/agg/AUTHORS
Normal file
2
src/agg/AUTHORS
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
2
src/agg/VERSION
Normal file
2
src/agg/VERSION
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
2.4
|
||||
svn revision 128
|
||||
1119
src/agg/agg_array.h
Normal file
1119
src/agg/agg_array.h
Normal file
File diff suppressed because it is too large
Load diff
574
src/agg/agg_basics.h
Normal file
574
src/agg/agg_basics.h
Normal file
|
|
@ -0,0 +1,574 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_BASICS_INCLUDED
|
||||
#define AGG_BASICS_INCLUDED
|
||||
|
||||
#include <cmath>
|
||||
#include "agg_config.h"
|
||||
|
||||
//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
|
||||
#ifdef AGG_CUSTOM_ALLOCATOR
|
||||
#include "agg_allocator.h"
|
||||
#else
|
||||
namespace agg
|
||||
{
|
||||
// The policy of all AGG containers and memory allocation strategy
|
||||
// in general is that no allocated data requires explicit construction.
|
||||
// It means that the allocator can be really simple; you can even
|
||||
// replace new/delete to malloc/free. The constructors and destructors
|
||||
// won't be called in this case, however everything will remain working.
|
||||
// The second argument of deallocate() is the size of the allocated
|
||||
// block. You can use this information if you wish.
|
||||
//------------------------------------------------------------pod_allocator
|
||||
template<class T> struct pod_allocator
|
||||
{
|
||||
static T* allocate(unsigned num) { return new T [num]; }
|
||||
static void deallocate(T* ptr, unsigned) { delete [] ptr; }
|
||||
};
|
||||
|
||||
// Single object allocator. It's also can be replaced with your custom
|
||||
// allocator. The difference is that it can only allocate a single
|
||||
// object and the constructor and destructor must be called.
|
||||
// In AGG there is no need to allocate an array of objects with
|
||||
// calling their constructors (only single ones). So that, if you
|
||||
// replace these new/delete to malloc/free make sure that the in-place
|
||||
// new is called and take care of calling the destructor too.
|
||||
//------------------------------------------------------------obj_allocator
|
||||
template<class T> struct obj_allocator
|
||||
{
|
||||
static T* allocate() { return new T; }
|
||||
static void deallocate(T* ptr) { delete ptr; }
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------------------------- Default basic types
|
||||
//
|
||||
// If the compiler has different capacity of the basic types you can redefine
|
||||
// them via the compiler command line or by generating agg_config.h that is
|
||||
// empty by default.
|
||||
//
|
||||
#ifndef AGG_INT8
|
||||
#define AGG_INT8 signed char
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT8U
|
||||
#define AGG_INT8U unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT16
|
||||
#define AGG_INT16 short
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT16U
|
||||
#define AGG_INT16U unsigned short
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT32
|
||||
#define AGG_INT32 int
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT32U
|
||||
#define AGG_INT32U unsigned
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT64
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#define AGG_INT64 signed __int64
|
||||
#else
|
||||
#define AGG_INT64 signed long long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT64U
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#define AGG_INT64U unsigned __int64
|
||||
#else
|
||||
#define AGG_INT64U unsigned long long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//------------------------------------------------ Some fixes for MS Visual C++
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable:4786) // Identifier was truncated...
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define AGG_INLINE __forceinline
|
||||
#else
|
||||
#define AGG_INLINE inline
|
||||
#endif
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
typedef AGG_INT8 int8; //----int8
|
||||
typedef AGG_INT8U int8u; //----int8u
|
||||
typedef AGG_INT16 int16; //----int16
|
||||
typedef AGG_INT16U int16u; //----int16u
|
||||
typedef AGG_INT32 int32; //----int32
|
||||
typedef AGG_INT32U int32u; //----int32u
|
||||
typedef AGG_INT64 int64; //----int64
|
||||
typedef AGG_INT64U int64u; //----int64u
|
||||
|
||||
#if defined(AGG_FISTP)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4035) //Disable warning "no return value"
|
||||
AGG_INLINE int iround(double v) //-------iround
|
||||
{
|
||||
int t;
|
||||
__asm fld qword ptr [v]
|
||||
__asm fistp dword ptr [t]
|
||||
__asm mov eax, dword ptr [t]
|
||||
}
|
||||
AGG_INLINE unsigned uround(double v) //-------uround
|
||||
{
|
||||
unsigned t;
|
||||
__asm fld qword ptr [v]
|
||||
__asm fistp dword ptr [t]
|
||||
__asm mov eax, dword ptr [t]
|
||||
}
|
||||
#pragma warning(pop)
|
||||
AGG_INLINE int ifloor(double v)
|
||||
{
|
||||
return int(floor(v));
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v) //-------ufloor
|
||||
{
|
||||
return unsigned(floor(v));
|
||||
}
|
||||
AGG_INLINE int iceil(double v)
|
||||
{
|
||||
return int(ceil(v));
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v) //--------uceil
|
||||
{
|
||||
return unsigned(ceil(v));
|
||||
}
|
||||
#elif defined(AGG_QIFIST)
|
||||
AGG_INLINE int iround(double v)
|
||||
{
|
||||
return int(v);
|
||||
}
|
||||
AGG_INLINE int uround(double v)
|
||||
{
|
||||
return unsigned(v);
|
||||
}
|
||||
AGG_INLINE int ifloor(double v)
|
||||
{
|
||||
return int(floor(v));
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v)
|
||||
{
|
||||
return unsigned(floor(v));
|
||||
}
|
||||
AGG_INLINE int iceil(double v)
|
||||
{
|
||||
return int(ceil(v));
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v)
|
||||
{
|
||||
return unsigned(ceil(v));
|
||||
}
|
||||
#else
|
||||
AGG_INLINE int iround(double v)
|
||||
{
|
||||
return int((v < 0.0) ? v - 0.5 : v + 0.5);
|
||||
}
|
||||
AGG_INLINE int uround(double v)
|
||||
{
|
||||
return unsigned(v + 0.5);
|
||||
}
|
||||
AGG_INLINE int ifloor(double v)
|
||||
{
|
||||
int i = int(v);
|
||||
return i - (i > v);
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v)
|
||||
{
|
||||
return unsigned(v);
|
||||
}
|
||||
AGG_INLINE int iceil(double v)
|
||||
{
|
||||
return int(ceil(v));
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v)
|
||||
{
|
||||
return unsigned(ceil(v));
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------saturation
|
||||
template<int Limit> struct saturation
|
||||
{
|
||||
AGG_INLINE static int iround(double v)
|
||||
{
|
||||
if(v < double(-Limit)) return -Limit;
|
||||
if(v > double( Limit)) return Limit;
|
||||
return agg::iround(v);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------mul_one
|
||||
template<unsigned Shift> struct mul_one
|
||||
{
|
||||
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned q = a * b + (1 << (Shift-1));
|
||||
return (q + (q >> Shift)) >> Shift;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
typedef unsigned char cover_type; //----cover_type
|
||||
enum cover_scale_e
|
||||
{
|
||||
cover_shift = 8, //----cover_shift
|
||||
cover_size = 1 << cover_shift, //----cover_size
|
||||
cover_mask = cover_size - 1, //----cover_mask
|
||||
cover_none = 0, //----cover_none
|
||||
cover_full = cover_mask //----cover_full
|
||||
};
|
||||
|
||||
//----------------------------------------------------poly_subpixel_scale_e
|
||||
// These constants determine the subpixel accuracy, to be more precise,
|
||||
// the number of bits of the fractional part of the coordinates.
|
||||
// The possible coordinate capacity in bits can be calculated by formula:
|
||||
// sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
|
||||
// 8-bits fractional part the capacity is 24 bits.
|
||||
enum poly_subpixel_scale_e
|
||||
{
|
||||
poly_subpixel_shift = 8, //----poly_subpixel_shift
|
||||
poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
|
||||
poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask
|
||||
};
|
||||
|
||||
//----------------------------------------------------------filling_rule_e
|
||||
enum filling_rule_e
|
||||
{
|
||||
fill_non_zero,
|
||||
fill_even_odd
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------pi
|
||||
const double pi = 3.14159265358979323846;
|
||||
|
||||
//------------------------------------------------------------------deg2rad
|
||||
inline double deg2rad(double deg)
|
||||
{
|
||||
return deg * pi / 180.0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------rad2deg
|
||||
inline double rad2deg(double rad)
|
||||
{
|
||||
return rad * 180.0 / pi;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------rect_base
|
||||
template<class T> struct rect_base
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef rect_base<T> self_type;
|
||||
T x1, y1, x2, y2;
|
||||
|
||||
rect_base() {}
|
||||
rect_base(T x1_, T y1_, T x2_, T y2_) :
|
||||
x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
|
||||
|
||||
void init(T x1_, T y1_, T x2_, T y2_)
|
||||
{
|
||||
x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_;
|
||||
}
|
||||
|
||||
const self_type& normalize()
|
||||
{
|
||||
T t;
|
||||
if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
|
||||
if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool clip(const self_type& r)
|
||||
{
|
||||
if(x2 > r.x2) x2 = r.x2;
|
||||
if(y2 > r.y2) y2 = r.y2;
|
||||
if(x1 < r.x1) x1 = r.x1;
|
||||
if(y1 < r.y1) y1 = r.y1;
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
}
|
||||
|
||||
bool hit_test(T x, T y) const
|
||||
{
|
||||
return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
|
||||
}
|
||||
|
||||
bool overlaps(const self_type& r) const
|
||||
{
|
||||
return !(r.x1 > x2 || r.x2 < x1
|
||||
|| r.y1 > y2 || r.y2 < y1);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------intersect_rectangles
|
||||
template<class Rect>
|
||||
inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
|
||||
// First process x2,y2 because the other order
|
||||
// results in Internal Compiler Error under
|
||||
// Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in
|
||||
// case of "Maximize Speed" optimization option.
|
||||
//-----------------
|
||||
if(r.x2 > r2.x2) r.x2 = r2.x2;
|
||||
if(r.y2 > r2.y2) r.y2 = r2.y2;
|
||||
if(r.x1 < r2.x1) r.x1 = r2.x1;
|
||||
if(r.y1 < r2.y1) r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------unite_rectangles
|
||||
template<class Rect>
|
||||
inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
if(r.x2 < r2.x2) r.x2 = r2.x2;
|
||||
if(r.y2 < r2.y2) r.y2 = r2.y2;
|
||||
if(r.x1 > r2.x1) r.x1 = r2.x1;
|
||||
if(r.y1 > r2.y1) r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
typedef rect_base<int> rect_i; //----rect_i
|
||||
typedef rect_base<float> rect_f; //----rect_f
|
||||
typedef rect_base<double> rect_d; //----rect_d
|
||||
|
||||
//---------------------------------------------------------path_commands_e
|
||||
enum path_commands_e
|
||||
{
|
||||
path_cmd_stop = 0, //----path_cmd_stop
|
||||
path_cmd_move_to = 1, //----path_cmd_move_to
|
||||
path_cmd_line_to = 2, //----path_cmd_line_to
|
||||
path_cmd_curve3 = 3, //----path_cmd_curve3
|
||||
path_cmd_curve4 = 4, //----path_cmd_curve4
|
||||
path_cmd_curveN = 5, //----path_cmd_curveN
|
||||
path_cmd_catrom = 6, //----path_cmd_catrom
|
||||
path_cmd_ubspline = 7, //----path_cmd_ubspline
|
||||
path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
|
||||
path_cmd_mask = 0x0F //----path_cmd_mask
|
||||
};
|
||||
|
||||
//------------------------------------------------------------path_flags_e
|
||||
enum path_flags_e
|
||||
{
|
||||
path_flags_none = 0, //----path_flags_none
|
||||
path_flags_ccw = 0x10, //----path_flags_ccw
|
||||
path_flags_cw = 0x20, //----path_flags_cw
|
||||
path_flags_close = 0x40, //----path_flags_close
|
||||
path_flags_mask = 0xF0 //----path_flags_mask
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------is_vertex
|
||||
inline bool is_vertex(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_move_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_drawing
|
||||
inline bool is_drawing(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_line_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------is_stop
|
||||
inline bool is_stop(unsigned c)
|
||||
{
|
||||
return c == path_cmd_stop;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_move_to
|
||||
inline bool is_move_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_move_to;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_line_to
|
||||
inline bool is_line_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_line_to;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_curve
|
||||
inline bool is_curve(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3 || c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve3
|
||||
inline bool is_curve3(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve4
|
||||
inline bool is_curve4(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_end_poly
|
||||
inline bool is_end_poly(unsigned c)
|
||||
{
|
||||
return (c & path_cmd_mask) == path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_close
|
||||
inline bool is_close(unsigned c)
|
||||
{
|
||||
return (c & ~(path_flags_cw | path_flags_ccw)) ==
|
||||
(path_cmd_end_poly | path_flags_close);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------is_next_poly
|
||||
inline bool is_next_poly(unsigned c)
|
||||
{
|
||||
return is_stop(c) || is_move_to(c) || is_end_poly(c);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------is_cw
|
||||
inline bool is_cw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_cw) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------is_ccw
|
||||
inline bool is_ccw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_ccw) != 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_oriented
|
||||
inline bool is_oriented(unsigned c)
|
||||
{
|
||||
return (c & (path_flags_cw | path_flags_ccw)) != 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_closed
|
||||
inline bool is_closed(unsigned c)
|
||||
{
|
||||
return (c & path_flags_close) != 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------get_close_flag
|
||||
inline unsigned get_close_flag(unsigned c)
|
||||
{
|
||||
return c & path_flags_close;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clear_orientation
|
||||
inline unsigned clear_orientation(unsigned c)
|
||||
{
|
||||
return c & ~(path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------get_orientation
|
||||
inline unsigned get_orientation(unsigned c)
|
||||
{
|
||||
return c & (path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------set_orientation
|
||||
inline unsigned set_orientation(unsigned c, unsigned o)
|
||||
{
|
||||
return clear_orientation(c) | o;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------point_base
|
||||
template<class T> struct point_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x,y;
|
||||
point_base() {}
|
||||
point_base(T x_, T y_) : x(x_), y(y_) {}
|
||||
};
|
||||
typedef point_base<int> point_i; //-----point_i
|
||||
typedef point_base<float> point_f; //-----point_f
|
||||
typedef point_base<double> point_d; //-----point_d
|
||||
|
||||
//-------------------------------------------------------------vertex_base
|
||||
template<class T> struct vertex_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x,y;
|
||||
unsigned cmd;
|
||||
vertex_base() {}
|
||||
vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
|
||||
};
|
||||
typedef vertex_base<int> vertex_i; //-----vertex_i
|
||||
typedef vertex_base<float> vertex_f; //-----vertex_f
|
||||
typedef vertex_base<double> vertex_d; //-----vertex_d
|
||||
|
||||
//----------------------------------------------------------------row_info
|
||||
template<class T> struct row_info
|
||||
{
|
||||
int x1, x2;
|
||||
T* ptr;
|
||||
row_info() {}
|
||||
row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------const_row_info
|
||||
template<class T> struct const_row_info
|
||||
{
|
||||
int x1, x2;
|
||||
const T* ptr;
|
||||
const_row_info() {}
|
||||
const_row_info(int x1_, int x2_, const T* ptr_) :
|
||||
x1(x1_), x2(x2_), ptr(ptr_) {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------is_equal_eps
|
||||
template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
|
||||
{
|
||||
bool neg1 = v1 < 0.0;
|
||||
bool neg2 = v2 < 0.0;
|
||||
|
||||
if (neg1 != neg2)
|
||||
return std::fabs(v1) < epsilon && std::fabs(v2) < epsilon;
|
||||
|
||||
int int1, int2;
|
||||
std::frexp(v1, &int1);
|
||||
std::frexp(v2, &int2);
|
||||
int min12 = int1 < int2 ? int1 : int2;
|
||||
|
||||
v1 = std::ldexp(v1, -min12);
|
||||
v2 = std::ldexp(v2, -min12);
|
||||
|
||||
return std::fabs(v1 - v2) < epsilon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
159
src/agg/agg_bezier_arc.h
Normal file
159
src/agg/agg_bezier_arc.h
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
|
||||
// 4, 7, 10, or 13 vertices.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_BEZIER_ARC_INCLUDED
|
||||
#define AGG_BEZIER_ARC_INCLUDED
|
||||
|
||||
#include "agg_conv_transform.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void arc_to_bezier(double cx, double cy, double rx, double ry,
|
||||
double start_angle, double sweep_angle,
|
||||
double* curve);
|
||||
|
||||
|
||||
//==============================================================bezier_arc
|
||||
//
|
||||
// See implemantaion agg_bezier_arc.cpp
|
||||
//
|
||||
class bezier_arc
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
|
||||
bezier_arc(double x, double y,
|
||||
double rx, double ry,
|
||||
double start_angle,
|
||||
double sweep_angle)
|
||||
{
|
||||
init(x, y, rx, ry, start_angle, sweep_angle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x, double y,
|
||||
double rx, double ry,
|
||||
double start_angle,
|
||||
double sweep_angle);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_vertex >= m_num_vertices) return path_cmd_stop;
|
||||
*x = m_vertices[m_vertex];
|
||||
*y = m_vertices[m_vertex + 1];
|
||||
m_vertex += 2;
|
||||
return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd;
|
||||
}
|
||||
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
// number of vertices. That is, for 1 vertex it returns 2.
|
||||
//--------------------------------------------------------------------
|
||||
unsigned num_vertices() const { return m_num_vertices; }
|
||||
const double* vertices() const { return m_vertices; }
|
||||
double* vertices() { return m_vertices; }
|
||||
|
||||
private:
|
||||
unsigned m_vertex;
|
||||
unsigned m_num_vertices;
|
||||
double m_vertices[26];
|
||||
unsigned m_cmd;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================================bezier_arc_svg
|
||||
// Compute an SVG-style bezier arc.
|
||||
//
|
||||
// Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
|
||||
// orientation of the ellipse are defined by two radii (rx, ry)
|
||||
// and an x-axis-rotation, which indicates how the ellipse as a whole
|
||||
// is rotated relative to the current coordinate system. The center
|
||||
// (cx, cy) of the ellipse is calculated automatically to satisfy the
|
||||
// constraints imposed by the other parameters.
|
||||
// large-arc-flag and sweep-flag contribute to the automatic calculations
|
||||
// and help determine how the arc is drawn.
|
||||
class bezier_arc_svg
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
|
||||
|
||||
bezier_arc_svg(double x1, double y1,
|
||||
double rx, double ry,
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x2, double y2) :
|
||||
m_arc(), m_radii_ok(false)
|
||||
{
|
||||
init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x1, double y1,
|
||||
double rx, double ry,
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x2, double y2);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool radii_ok() const { return m_radii_ok; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_arc.rewind(0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
return m_arc.vertex(x, y);
|
||||
}
|
||||
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
// number of vertices. That is, for 1 vertex it returns 2.
|
||||
//--------------------------------------------------------------------
|
||||
unsigned num_vertices() const { return m_arc.num_vertices(); }
|
||||
const double* vertices() const { return m_arc.vertices(); }
|
||||
double* vertices() { return m_arc.vertices(); }
|
||||
|
||||
private:
|
||||
bezier_arc m_arc;
|
||||
bool m_radii_ok;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
333
src/agg/agg_clip_liang_barsky.h
Normal file
333
src/agg/agg_clip_liang_barsky.h
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Liang-Barsky clipping
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
|
||||
#define AGG_CLIP_LIANG_BARSKY_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum clipping_flags_e
|
||||
{
|
||||
clipping_flags_x1_clipped = 4,
|
||||
clipping_flags_x2_clipped = 1,
|
||||
clipping_flags_y1_clipped = 8,
|
||||
clipping_flags_y2_clipped = 2,
|
||||
clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
|
||||
clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
|
||||
};
|
||||
|
||||
//----------------------------------------------------------clipping_flags
|
||||
// Determine the clipping code of the vertex according to the
|
||||
// Cyrus-Beck line clipping algorithm
|
||||
//
|
||||
// | |
|
||||
// 0110 | 0010 | 0011
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y2
|
||||
// | |
|
||||
// 0100 | 0000 | 0001
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y1
|
||||
// | |
|
||||
// 1100 | 1000 | 1001
|
||||
// | |
|
||||
// clip_box.x1 clip_box.x2
|
||||
//
|
||||
//
|
||||
template<class T>
|
||||
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
return (x > clip_box.x2) |
|
||||
((y > clip_box.y2) << 1) |
|
||||
((x < clip_box.x1) << 2) |
|
||||
((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------clipping_flags_x
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
|
||||
{
|
||||
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------clipping_flags_y
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------clip_liang_barsky
|
||||
template<class T>
|
||||
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
|
||||
const rect_base<T>& clip_box,
|
||||
T* x, T* y)
|
||||
{
|
||||
const double nearzero = 1e-30;
|
||||
|
||||
double deltax = x2 - x1;
|
||||
double deltay = y2 - y1;
|
||||
double xin;
|
||||
double xout;
|
||||
double yin;
|
||||
double yout;
|
||||
double tinx;
|
||||
double tiny;
|
||||
double toutx;
|
||||
double touty;
|
||||
double tin1;
|
||||
double tin2;
|
||||
double tout1;
|
||||
unsigned np = 0;
|
||||
|
||||
if(deltax == 0.0)
|
||||
{
|
||||
// bump off of the vertical
|
||||
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
|
||||
}
|
||||
|
||||
if(deltay == 0.0)
|
||||
{
|
||||
// bump off of the horizontal
|
||||
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
|
||||
}
|
||||
|
||||
if(deltax > 0.0)
|
||||
{
|
||||
// points to right
|
||||
xin = clip_box.x1;
|
||||
xout = clip_box.x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
xin = clip_box.x2;
|
||||
xout = clip_box.x1;
|
||||
}
|
||||
|
||||
if(deltay > 0.0)
|
||||
{
|
||||
// points up
|
||||
yin = clip_box.y1;
|
||||
yout = clip_box.y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
yin = clip_box.y2;
|
||||
yout = clip_box.y1;
|
||||
}
|
||||
|
||||
tinx = (xin - x1) / deltax;
|
||||
tiny = (yin - y1) / deltay;
|
||||
|
||||
if (tinx < tiny)
|
||||
{
|
||||
// hits x first
|
||||
tin1 = tinx;
|
||||
tin2 = tiny;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hits y first
|
||||
tin1 = tiny;
|
||||
tin2 = tinx;
|
||||
}
|
||||
|
||||
if(tin1 <= 1.0)
|
||||
{
|
||||
if(0.0 < tin1)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yin;
|
||||
++np;
|
||||
}
|
||||
|
||||
if(tin2 <= 1.0)
|
||||
{
|
||||
toutx = (xout - x1) / deltax;
|
||||
touty = (yout - y1) / deltay;
|
||||
|
||||
tout1 = (toutx < touty) ? toutx : touty;
|
||||
|
||||
if(tin2 > 0.0 || tout1 > 0.0)
|
||||
{
|
||||
if(tin2 <= tout1)
|
||||
{
|
||||
if(tin2 > 0.0)
|
||||
{
|
||||
if(tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)(y1 + tinx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + tiny * deltax);
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
|
||||
if(tout1 < 1.0)
|
||||
{
|
||||
if(toutx < touty)
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)(y1 + toutx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + touty * deltax);
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = x2;
|
||||
*y++ = y2;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return np;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class T>
|
||||
bool clip_move_point(T x1, T y1, T x2, T y2,
|
||||
const rect_base<T>& clip_box,
|
||||
T* x, T* y, unsigned flags)
|
||||
{
|
||||
T bound;
|
||||
|
||||
if(flags & clipping_flags_x_clipped)
|
||||
{
|
||||
if(x1 == x2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
|
||||
*y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
|
||||
*x = bound;
|
||||
}
|
||||
|
||||
flags = clipping_flags_y(*y, clip_box);
|
||||
if(flags & clipping_flags_y_clipped)
|
||||
{
|
||||
if(y1 == y2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
|
||||
*x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
|
||||
*y = bound;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clip_line_segment
|
||||
// Returns: ret >= 4 - Fully clipped
|
||||
// (ret & 1) != 0 - First point has been moved
|
||||
// (ret & 2) != 0 - Second point has been moved
|
||||
//
|
||||
template<class T>
|
||||
unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2,
|
||||
const rect_base<T>& clip_box)
|
||||
{
|
||||
unsigned f1 = clipping_flags(*x1, *y1, clip_box);
|
||||
unsigned f2 = clipping_flags(*x2, *y2, clip_box);
|
||||
unsigned ret = 0;
|
||||
|
||||
if((f2 | f1) == 0)
|
||||
{
|
||||
// Fully visible
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((f1 & clipping_flags_x_clipped) != 0 &&
|
||||
(f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
if((f1 & clipping_flags_y_clipped) != 0 &&
|
||||
(f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
T tx1 = *x1;
|
||||
T ty1 = *y1;
|
||||
T tx2 = *x2;
|
||||
T ty2 = *y2;
|
||||
if(f1)
|
||||
{
|
||||
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if(*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 1;
|
||||
}
|
||||
if(f2)
|
||||
{
|
||||
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if(*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1047
src/agg/agg_color_gray.h
Normal file
1047
src/agg/agg_color_gray.h
Normal file
File diff suppressed because it is too large
Load diff
1353
src/agg/agg_color_rgba.h
Normal file
1353
src/agg/agg_color_rgba.h
Normal file
File diff suppressed because it is too large
Load diff
44
src/agg/agg_config.h
Normal file
44
src/agg/agg_config.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef AGG_CONFIG_INCLUDED
|
||||
#define AGG_CONFIG_INCLUDED
|
||||
|
||||
// This file can be used to redefine certain data types.
|
||||
|
||||
//---------------------------------------
|
||||
// 1. Default basic types such as:
|
||||
//
|
||||
// AGG_INT8
|
||||
// AGG_INT8U
|
||||
// AGG_INT16
|
||||
// AGG_INT16U
|
||||
// AGG_INT32
|
||||
// AGG_INT32U
|
||||
// AGG_INT64
|
||||
// AGG_INT64U
|
||||
//
|
||||
// Just replace this file with new defines if necessary.
|
||||
// For example, if your compiler doesn't have a 64 bit integer type
|
||||
// you can still use AGG if you define the follows:
|
||||
//
|
||||
// #define AGG_INT64 int
|
||||
// #define AGG_INT64U unsigned
|
||||
//
|
||||
// It will result in overflow in 16 bit-per-component image/pattern resampling
|
||||
// but it won't result any crash and the rest of the library will remain
|
||||
// fully functional.
|
||||
|
||||
|
||||
//---------------------------------------
|
||||
// 2. Default rendering_buffer type. Can be:
|
||||
//
|
||||
// Provides faster access for massive pixel operations,
|
||||
// such as blur, image filtering:
|
||||
// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
|
||||
//
|
||||
// Provides cheaper creation and destruction (no mem allocs):
|
||||
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
|
||||
//
|
||||
// You can still use both of them simultaneously in your applications
|
||||
// This #define is used only for default rendering_buffer type,
|
||||
// in short hand typedefs like pixfmt_rgba32.
|
||||
|
||||
#endif
|
||||
68
src/agg/agg_conv_transform.h
Normal file
68
src/agg/agg_conv_transform.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class conv_transform
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_TRANSFORM_INCLUDED
|
||||
#define AGG_CONV_TRANSFORM_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------------------conv_transform
|
||||
template<class VertexSource, class Transformer=trans_affine> class conv_transform
|
||||
{
|
||||
public:
|
||||
conv_transform(VertexSource& source, Transformer& tr) :
|
||||
m_source(&source), m_trans(&tr) {}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
m_trans->transform(x, y);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void transformer(Transformer& tr)
|
||||
{
|
||||
m_trans = &tr;
|
||||
}
|
||||
|
||||
private:
|
||||
conv_transform(const conv_transform<VertexSource>&);
|
||||
const conv_transform<VertexSource>&
|
||||
operator = (const conv_transform<VertexSource>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
Transformer* m_trans;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
132
src/agg/agg_gamma_functions.h
Normal file
132
src/agg/agg_gamma_functions.h
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED
|
||||
#define AGG_GAMMA_FUNCTIONS_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//===============================================================gamma_none
|
||||
struct gamma_none
|
||||
{
|
||||
double operator()(double x) const { return x; }
|
||||
};
|
||||
|
||||
|
||||
//==============================================================gamma_power
|
||||
class gamma_power
|
||||
{
|
||||
public:
|
||||
gamma_power() : m_gamma(1.0) {}
|
||||
gamma_power(double g) : m_gamma(g) {}
|
||||
|
||||
void gamma(double g) { m_gamma = g; }
|
||||
double gamma() const { return m_gamma; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
return pow(x, m_gamma);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gamma_threshold
|
||||
class gamma_threshold
|
||||
{
|
||||
public:
|
||||
gamma_threshold() : m_threshold(0.5) {}
|
||||
gamma_threshold(double t) : m_threshold(t) {}
|
||||
|
||||
void threshold(double t) { m_threshold = t; }
|
||||
double threshold() const { return m_threshold; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
return (x < m_threshold) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_threshold;
|
||||
};
|
||||
|
||||
|
||||
//============================================================gamma_linear
|
||||
class gamma_linear
|
||||
{
|
||||
public:
|
||||
gamma_linear() : m_start(0.0), m_end(1.0) {}
|
||||
gamma_linear(double s, double e) : m_start(s), m_end(e) {}
|
||||
|
||||
void set(double s, double e) { m_start = s; m_end = e; }
|
||||
void start(double s) { m_start = s; }
|
||||
void end(double e) { m_end = e; }
|
||||
double start() const { return m_start; }
|
||||
double end() const { return m_end; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
if(x < m_start) return 0.0;
|
||||
if(x > m_end) return 1.0;
|
||||
return (x - m_start) / (m_end - m_start);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_start;
|
||||
double m_end;
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gamma_multiply
|
||||
class gamma_multiply
|
||||
{
|
||||
public:
|
||||
gamma_multiply() : m_mul(1.0) {}
|
||||
gamma_multiply(double v) : m_mul(v) {}
|
||||
|
||||
void value(double v) { m_mul = v; }
|
||||
double value() const { return m_mul; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
double y = x * m_mul;
|
||||
if(y > 1.0) y = 1.0;
|
||||
return y;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_mul;
|
||||
};
|
||||
|
||||
inline double sRGB_to_linear(double x)
|
||||
{
|
||||
return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
|
||||
}
|
||||
|
||||
inline double linear_to_sRGB(double x)
|
||||
{
|
||||
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
300
src/agg/agg_gamma_lut.h
Normal file
300
src/agg/agg_gamma_lut.h
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_GAMMA_LUT_INCLUDED
|
||||
#define AGG_GAMMA_LUT_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
#include "agg_gamma_functions.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
template<class LoResT=int8u,
|
||||
class HiResT=int8u,
|
||||
unsigned GammaShift=8,
|
||||
unsigned HiResShift=8> class gamma_lut
|
||||
{
|
||||
public:
|
||||
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
|
||||
|
||||
enum gamma_scale_e
|
||||
{
|
||||
gamma_shift = GammaShift,
|
||||
gamma_size = 1 << gamma_shift,
|
||||
gamma_mask = gamma_size - 1
|
||||
};
|
||||
|
||||
enum hi_res_scale_e
|
||||
{
|
||||
hi_res_shift = HiResShift,
|
||||
hi_res_size = 1 << hi_res_shift,
|
||||
hi_res_mask = hi_res_size - 1
|
||||
};
|
||||
|
||||
~gamma_lut()
|
||||
{
|
||||
pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
|
||||
pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
|
||||
}
|
||||
|
||||
gamma_lut() :
|
||||
m_gamma(1.0),
|
||||
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
|
||||
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < gamma_size; i++)
|
||||
{
|
||||
m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift));
|
||||
}
|
||||
|
||||
for(i = 0; i < hi_res_size; i++)
|
||||
{
|
||||
m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift));
|
||||
}
|
||||
}
|
||||
|
||||
gamma_lut(double g) :
|
||||
m_gamma(1.0),
|
||||
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
|
||||
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||
{
|
||||
gamma(g);
|
||||
}
|
||||
|
||||
void gamma(double g)
|
||||
{
|
||||
m_gamma = g;
|
||||
|
||||
unsigned i;
|
||||
for(i = 0; i < gamma_size; i++)
|
||||
{
|
||||
m_dir_gamma[i] = (HiResT)
|
||||
uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
|
||||
}
|
||||
|
||||
double inv_g = 1.0 / g;
|
||||
for(i = 0; i < hi_res_size; i++)
|
||||
{
|
||||
m_inv_gamma[i] = (LoResT)
|
||||
uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
|
||||
}
|
||||
}
|
||||
|
||||
double gamma() const
|
||||
{
|
||||
return m_gamma;
|
||||
}
|
||||
|
||||
HiResT dir(LoResT v) const
|
||||
{
|
||||
return m_dir_gamma[unsigned(v)];
|
||||
}
|
||||
|
||||
LoResT inv(HiResT v) const
|
||||
{
|
||||
return m_inv_gamma[unsigned(v)];
|
||||
}
|
||||
|
||||
private:
|
||||
gamma_lut(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
double m_gamma;
|
||||
HiResT* m_dir_gamma;
|
||||
LoResT* m_inv_gamma;
|
||||
};
|
||||
|
||||
//
|
||||
// sRGB support classes
|
||||
//
|
||||
|
||||
// sRGB_lut - implements sRGB conversion for the various types.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class LinearType>
|
||||
class sRGB_lut;
|
||||
|
||||
template<>
|
||||
class sRGB_lut<float>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
for (int i = 0; i <= 255; ++i)
|
||||
{
|
||||
m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
|
||||
}
|
||||
for (int i = 0; i <= 65535; ++i)
|
||||
{
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
|
||||
}
|
||||
}
|
||||
|
||||
float dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
int8u inv(float v) const
|
||||
{
|
||||
return m_inv_table[int16u(0.5 + v * 65535)];
|
||||
}
|
||||
|
||||
private:
|
||||
float m_dir_table[256];
|
||||
int8u m_inv_table[65536];
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_lut<int16u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
for (int i = 0; i <= 255; ++i)
|
||||
{
|
||||
m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
|
||||
}
|
||||
for (int i = 0; i <= 65535; ++i)
|
||||
{
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
|
||||
}
|
||||
}
|
||||
|
||||
int16u dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
int8u inv(int16u v) const
|
||||
{
|
||||
return m_inv_table[v];
|
||||
}
|
||||
|
||||
private:
|
||||
int16u m_dir_table[256];
|
||||
int8u m_inv_table[65536];
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_lut<int8u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
for (int i = 0; i <= 255; ++i)
|
||||
{
|
||||
m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
|
||||
}
|
||||
}
|
||||
|
||||
int8u dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
int8u inv(int8u v) const
|
||||
{
|
||||
return m_inv_table[v];
|
||||
}
|
||||
|
||||
private:
|
||||
int8u m_dir_table[256];
|
||||
int8u m_inv_table[256];
|
||||
};
|
||||
|
||||
// Common base class for sRGB_conv objects. Defines an internal
|
||||
// sRGB_lut object so that users don't have to.
|
||||
template<class T>
|
||||
class sRGB_conv_base
|
||||
{
|
||||
public:
|
||||
static T rgb_from_sRGB(int8u x)
|
||||
{
|
||||
return lut.dir(x);
|
||||
}
|
||||
|
||||
static int8u rgb_to_sRGB(T x)
|
||||
{
|
||||
return lut.inv(x);
|
||||
}
|
||||
|
||||
private:
|
||||
static sRGB_lut<T> lut;
|
||||
};
|
||||
|
||||
// Definition of sRGB_conv_base::lut. Due to the fact that this a template,
|
||||
// we don't need to place the definition in a cpp file. Hurrah.
|
||||
template<class T>
|
||||
sRGB_lut<T> sRGB_conv_base<T>::lut;
|
||||
|
||||
// Wrapper for sRGB-linear conversion.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class T>
|
||||
class sRGB_conv;
|
||||
|
||||
template<>
|
||||
class sRGB_conv<float> : public sRGB_conv_base<float>
|
||||
{
|
||||
public:
|
||||
static float alpha_from_sRGB(int8u x)
|
||||
{
|
||||
static const double y = 1 / 255.0;
|
||||
return float(x * y);
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(float x)
|
||||
{
|
||||
return int8u(0.5 + x * 255);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
|
||||
{
|
||||
public:
|
||||
static int16u alpha_from_sRGB(int8u x)
|
||||
{
|
||||
return (x << 8) | x;
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(int16u x)
|
||||
{
|
||||
return x >> 8;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
|
||||
{
|
||||
public:
|
||||
static int8u alpha_from_sRGB(int8u x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(int8u x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
437
src/agg/agg_math.h
Normal file
437
src/agg/agg_math.h
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
|
||||
// Contact: castor.vulgaris@gmail.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_MATH_INCLUDED
|
||||
#define AGG_MATH_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//------------------------------------------------------vertex_dist_epsilon
|
||||
// Coinciding points maximal distance (Epsilon)
|
||||
const double vertex_dist_epsilon = 1e-14;
|
||||
|
||||
//-----------------------------------------------------intersection_epsilon
|
||||
// See calc_intersection
|
||||
const double intersection_epsilon = 1.0e-30;
|
||||
|
||||
//------------------------------------------------------------cross_product
|
||||
AGG_INLINE double cross_product(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------point_in_triangle
|
||||
AGG_INLINE bool point_in_triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x, double y)
|
||||
{
|
||||
bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
|
||||
bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
|
||||
bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
|
||||
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------calc_distance
|
||||
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
return sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------calc_sq_distance
|
||||
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
//------------------------------------------------calc_line_point_distance
|
||||
AGG_INLINE double calc_line_point_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
double d = sqrt(dx * dx + dy * dy);
|
||||
if(d < vertex_dist_epsilon)
|
||||
{
|
||||
return calc_distance(x1, y1, x, y);
|
||||
}
|
||||
return ((x - x2) * dy - (y - y2) * dx) / d;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_line_point_u
|
||||
AGG_INLINE double calc_segment_point_u(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
|
||||
if(dx == 0 && dy == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double pdx = x - x1;
|
||||
double pdy = y - y1;
|
||||
|
||||
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y,
|
||||
double u)
|
||||
{
|
||||
if(u <= 0)
|
||||
{
|
||||
return calc_sq_distance(x, y, x1, y1);
|
||||
}
|
||||
else
|
||||
if(u >= 1)
|
||||
{
|
||||
return calc_sq_distance(x, y, x2, y2);
|
||||
}
|
||||
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
|
||||
}
|
||||
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
return
|
||||
calc_segment_point_sq_distance(
|
||||
x1, y1, x2, y2, x, y,
|
||||
calc_segment_point_u(x1, y1, x2, y2, x, y));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_intersection
|
||||
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
|
||||
double cx, double cy, double dx, double dy,
|
||||
double* x, double* y)
|
||||
{
|
||||
double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
|
||||
double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
|
||||
if(fabs(den) < intersection_epsilon) return false;
|
||||
double r = num / den;
|
||||
*x = ax + r * (bx-ax);
|
||||
*y = ay + r * (by-ay);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------intersection_exists
|
||||
AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
|
||||
double x3, double y3, double x4, double y4)
|
||||
{
|
||||
// It's less expensive but you can't control the
|
||||
// boundary conditions: Less or LessEqual
|
||||
double dx1 = x2 - x1;
|
||||
double dy1 = y2 - y1;
|
||||
double dx2 = x4 - x3;
|
||||
double dy2 = y4 - y3;
|
||||
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
|
||||
((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
|
||||
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
|
||||
((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
|
||||
|
||||
// It's is more expensive but more flexible
|
||||
// in terms of boundary conditions.
|
||||
//--------------------
|
||||
//double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
|
||||
//if(fabs(den) < intersection_epsilon) return false;
|
||||
//double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
|
||||
//double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
|
||||
//double ua = nom1 / den;
|
||||
//double ub = nom2 / den;
|
||||
//return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------calc_orthogonal
|
||||
AGG_INLINE void calc_orthogonal(double thickness,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double* x, double* y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
double d = sqrt(dx*dx + dy*dy);
|
||||
*x = thickness * dy / d;
|
||||
*y = -thickness * dx / d;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------dilate_triangle
|
||||
AGG_INLINE void dilate_triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double *x, double* y,
|
||||
double d)
|
||||
{
|
||||
double dx1=0.0;
|
||||
double dy1=0.0;
|
||||
double dx2=0.0;
|
||||
double dy2=0.0;
|
||||
double dx3=0.0;
|
||||
double dy3=0.0;
|
||||
double loc = cross_product(x1, y1, x2, y2, x3, y3);
|
||||
if(fabs(loc) > intersection_epsilon)
|
||||
{
|
||||
if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
|
||||
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
|
||||
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
|
||||
}
|
||||
*x++ = x1 + dx1; *y++ = y1 + dy1;
|
||||
*x++ = x2 + dx1; *y++ = y2 + dy1;
|
||||
*x++ = x2 + dx2; *y++ = y2 + dy2;
|
||||
*x++ = x3 + dx2; *y++ = y3 + dy2;
|
||||
*x++ = x3 + dx3; *y++ = y3 + dy3;
|
||||
*x++ = x1 + dx3; *y++ = y1 + dy3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------calc_triangle_area
|
||||
AGG_INLINE double calc_triangle_area(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_polygon_area
|
||||
template<class Storage> double calc_polygon_area(const Storage& st)
|
||||
{
|
||||
unsigned i;
|
||||
double sum = 0.0;
|
||||
double x = st[0].x;
|
||||
double y = st[0].y;
|
||||
double xs = x;
|
||||
double ys = y;
|
||||
|
||||
for(i = 1; i < st.size(); i++)
|
||||
{
|
||||
const typename Storage::value_type& v = st[i];
|
||||
sum += x * v.y - y * v.x;
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
}
|
||||
return (sum + x * ys - y * xs) * 0.5;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Tables for fast sqrt
|
||||
extern int16u g_sqrt_table[1024];
|
||||
extern int8 g_elder_bit_table[256];
|
||||
|
||||
|
||||
//---------------------------------------------------------------fast_sqrt
|
||||
//Fast integer Sqrt - really fast: no cycles, divisions or multiplications
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4035) //Disable warning "no return value"
|
||||
#endif
|
||||
AGG_INLINE unsigned fast_sqrt(unsigned val)
|
||||
{
|
||||
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
|
||||
//For Ix86 family processors this assembler code is used.
|
||||
//The key command here is bsr - determination the number of the most
|
||||
//significant bit of the value. For other processors
|
||||
//(and maybe compilers) the pure C "#else" section is used.
|
||||
__asm
|
||||
{
|
||||
mov ebx, val
|
||||
mov edx, 11
|
||||
bsr ecx, ebx
|
||||
sub ecx, 9
|
||||
jle less_than_9_bits
|
||||
shr ecx, 1
|
||||
adc ecx, 0
|
||||
sub edx, ecx
|
||||
shl ecx, 1
|
||||
shr ebx, cl
|
||||
less_than_9_bits:
|
||||
xor eax, eax
|
||||
mov ax, g_sqrt_table[ebx*2]
|
||||
mov ecx, edx
|
||||
shr eax, cl
|
||||
}
|
||||
#else
|
||||
|
||||
//This code is actually pure C and portable to most
|
||||
//arcitectures including 64bit ones.
|
||||
unsigned t = val;
|
||||
int bit=0;
|
||||
unsigned shift = 11;
|
||||
|
||||
//The following piece of code is just an emulation of the
|
||||
//Ix86 assembler command "bsr" (see above). However on old
|
||||
//Intels (like Intel MMX 233MHz) this code is about twice
|
||||
//faster (sic!) then just one "bsr". On PIII and PIV the
|
||||
//bsr is optimized quite well.
|
||||
bit = t >> 24;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = (t >> 16) & 0xFF;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = (t >> 8) & 0xFF;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = g_elder_bit_table[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This code calculates the sqrt.
|
||||
bit -= 9;
|
||||
if(bit > 0)
|
||||
{
|
||||
bit = (bit >> 1) + (bit & 1);
|
||||
shift -= bit;
|
||||
val >>= (bit << 1);
|
||||
}
|
||||
return g_sqrt_table[val] >> shift;
|
||||
#endif
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------besj
|
||||
// Function BESJ calculates Bessel function of first kind of order n
|
||||
// Arguments:
|
||||
// n - an integer (>=0), the order
|
||||
// x - value at which the Bessel function is required
|
||||
//--------------------
|
||||
// C++ Mathematical Library
|
||||
// Convereted from equivalent FORTRAN library
|
||||
// Converetd by Gareth Walker for use by course 392 computational project
|
||||
// All functions tested and yield the same results as the corresponding
|
||||
// FORTRAN versions.
|
||||
//
|
||||
// If you have any problems using these functions please report them to
|
||||
// M.Muldoon@UMIST.ac.uk
|
||||
//
|
||||
// Documentation available on the web
|
||||
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
|
||||
// Version 1.0 8/98
|
||||
// 29 October, 1999
|
||||
//--------------------
|
||||
// Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
|
||||
//------------------------------------------------------------------------
|
||||
inline double besj(double x, int n)
|
||||
{
|
||||
if(n < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
double d = 1E-6;
|
||||
double b = 0;
|
||||
if(fabs(x) <= d)
|
||||
{
|
||||
if(n != 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
double b1 = 0; // b1 is the value from the previous iteration
|
||||
// Set up a starting order for recurrence
|
||||
int m1 = (int)fabs(x) + 6;
|
||||
if(fabs(x) > 5)
|
||||
{
|
||||
m1 = (int)(fabs(1.4 * x + 60 / x));
|
||||
}
|
||||
int m2 = (int)(n + 2 + fabs(x) / 4);
|
||||
if (m1 > m2)
|
||||
{
|
||||
m2 = m1;
|
||||
}
|
||||
|
||||
// Apply recurrence down from curent max order
|
||||
for(;;)
|
||||
{
|
||||
double c3 = 0;
|
||||
double c2 = 1E-30;
|
||||
double c4 = 0;
|
||||
int m8 = 1;
|
||||
if (m2 / 2 * 2 == m2)
|
||||
{
|
||||
m8 = -1;
|
||||
}
|
||||
int imax = m2 - 2;
|
||||
for (int i = 1; i <= imax; i++)
|
||||
{
|
||||
double c6 = 2 * (m2 - i) * c2 / x - c3;
|
||||
c3 = c2;
|
||||
c2 = c6;
|
||||
if(m2 - i - 1 == n)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
m8 = -1 * m8;
|
||||
if (m8 > 0)
|
||||
{
|
||||
c4 = c4 + 2 * c6;
|
||||
}
|
||||
}
|
||||
double c6 = 2 * c2 / x - c3;
|
||||
if(n == 0)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
c4 += c6;
|
||||
b /= c4;
|
||||
if(fabs(b - b1) < d)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
b1 = b;
|
||||
m2 += 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1582
src/agg/agg_path_storage.h
Normal file
1582
src/agg/agg_path_storage.h
Normal file
File diff suppressed because it is too large
Load diff
97
src/agg/agg_pixfmt_base.h
Normal file
97
src/agg/agg_pixfmt_base.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_BASE_INCLUDED
|
||||
#define AGG_PIXFMT_BASE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_gray.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
struct pixfmt_gray_tag
|
||||
{
|
||||
};
|
||||
|
||||
struct pixfmt_rgb_tag
|
||||
{
|
||||
};
|
||||
|
||||
struct pixfmt_rgba_tag
|
||||
{
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------blender_base
|
||||
template<class ColorT, class Order = void>
|
||||
struct blender_base
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
|
||||
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
|
||||
{
|
||||
if (cover > cover_none)
|
||||
{
|
||||
rgba c(
|
||||
color_type::to_double(r),
|
||||
color_type::to_double(g),
|
||||
color_type::to_double(b),
|
||||
color_type::to_double(a));
|
||||
|
||||
if (cover < cover_full)
|
||||
{
|
||||
double x = double(cover) / cover_full;
|
||||
c.r *= x;
|
||||
c.g *= x;
|
||||
c.b *= x;
|
||||
c.a *= x;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
else return rgba::no_color();
|
||||
}
|
||||
|
||||
static rgba get(const value_type* p, cover_type cover = cover_full)
|
||||
{
|
||||
return get(
|
||||
p[order_type::R],
|
||||
p[order_type::G],
|
||||
p[order_type::B],
|
||||
p[order_type::A],
|
||||
cover);
|
||||
}
|
||||
|
||||
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
|
||||
{
|
||||
p[order_type::R] = r;
|
||||
p[order_type::G] = g;
|
||||
p[order_type::B] = b;
|
||||
p[order_type::A] = a;
|
||||
}
|
||||
|
||||
static void set(value_type* p, const rgba& c)
|
||||
{
|
||||
p[order_type::R] = color_type::from_double(c.r);
|
||||
p[order_type::G] = color_type::from_double(c.g);
|
||||
p[order_type::B] = color_type::from_double(c.b);
|
||||
p[order_type::A] = color_type::from_double(c.a);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
738
src/agg/agg_pixfmt_gray.h
Normal file
738
src/agg/agg_pixfmt_gray.h
Normal file
|
|
@ -0,0 +1,738 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_GRAY_INCLUDED
|
||||
#define AGG_PIXFMT_GRAY_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_pixfmt_base.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//============================================================blender_gray
|
||||
template<class ColorT> struct blender_gray
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
// Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
|
||||
// compositing function. Since the render buffer is opaque we skip the
|
||||
// initial premultiply and final demultiply.
|
||||
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cv, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p, cv, color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cv, value_type alpha)
|
||||
{
|
||||
*p = color_type::lerp(*p, cv, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//======================================================blender_gray_pre
|
||||
template<class ColorT> struct blender_gray_pre
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
// Blend pixels using the premultiplied form of Alvy-Ray Smith's
|
||||
// compositing function.
|
||||
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cv, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cv, value_type alpha)
|
||||
{
|
||||
*p = color_type::prelerp(*p, cv, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=====================================================apply_gamma_dir_gray
|
||||
template<class ColorT, class GammaLut> class apply_gamma_dir_gray
|
||||
{
|
||||
public:
|
||||
typedef typename ColorT::value_type value_type;
|
||||
|
||||
apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {}
|
||||
|
||||
AGG_INLINE void operator () (value_type* p)
|
||||
{
|
||||
*p = m_gamma.dir(*p);
|
||||
}
|
||||
|
||||
private:
|
||||
const GammaLut& m_gamma;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=====================================================apply_gamma_inv_gray
|
||||
template<class ColorT, class GammaLut> class apply_gamma_inv_gray
|
||||
{
|
||||
public:
|
||||
typedef typename ColorT::value_type value_type;
|
||||
|
||||
apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {}
|
||||
|
||||
AGG_INLINE void operator () (value_type* p)
|
||||
{
|
||||
*p = m_gamma.inv(*p);
|
||||
}
|
||||
|
||||
private:
|
||||
const GammaLut& m_gamma;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=================================================pixfmt_alpha_blend_gray
|
||||
template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0>
|
||||
class pixfmt_alpha_blend_gray
|
||||
{
|
||||
public:
|
||||
typedef pixfmt_gray_tag pixfmt_category;
|
||||
typedef RenBuf rbuf_type;
|
||||
typedef typename rbuf_type::row_data row_data;
|
||||
typedef Blender blender_type;
|
||||
typedef typename blender_type::color_type color_type;
|
||||
typedef int order_type; // A fake one
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
enum
|
||||
{
|
||||
num_components = 1,
|
||||
pix_width = sizeof(value_type) * Step,
|
||||
pix_step = Step,
|
||||
pix_offset = Offset,
|
||||
};
|
||||
struct pixel_type
|
||||
{
|
||||
value_type c[num_components];
|
||||
|
||||
void set(value_type v)
|
||||
{
|
||||
c[0] = v;
|
||||
}
|
||||
|
||||
void set(const color_type& color)
|
||||
{
|
||||
set(color.v);
|
||||
}
|
||||
|
||||
void get(value_type& v) const
|
||||
{
|
||||
v = c[0];
|
||||
}
|
||||
|
||||
color_type get() const
|
||||
{
|
||||
return color_type(c[0]);
|
||||
}
|
||||
|
||||
pixel_type* next()
|
||||
{
|
||||
return (pixel_type*)(c + pix_step);
|
||||
}
|
||||
|
||||
const pixel_type* next() const
|
||||
{
|
||||
return (const pixel_type*)(c + pix_step);
|
||||
}
|
||||
|
||||
pixel_type* advance(int n)
|
||||
{
|
||||
return (pixel_type*)(c + n * pix_step);
|
||||
}
|
||||
|
||||
const pixel_type* advance(int n) const
|
||||
{
|
||||
return (const pixel_type*)(c + n * pix_step);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p,
|
||||
value_type v, value_type a,
|
||||
unsigned cover)
|
||||
{
|
||||
blender_type::blend_pix(p->c, v, a, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a)
|
||||
{
|
||||
blender_type::blend_pix(p->c, v, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
|
||||
{
|
||||
blender_type::blend_pix(p->c, c.v, c.a, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
|
||||
{
|
||||
blender_type::blend_pix(p->c, c.v, c.a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
if (c.is_opaque() && cover == cover_mask)
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c, cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
if (c.is_opaque())
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
explicit pixfmt_alpha_blend_gray(rbuf_type& rb) :
|
||||
m_rbuf(&rb)
|
||||
{}
|
||||
void attach(rbuf_type& rb) { m_rbuf = &rb; }
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
template<class PixFmt>
|
||||
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rect_i r(x1, y1, x2, y2);
|
||||
if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
|
||||
{
|
||||
int stride = pixf.stride();
|
||||
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
|
||||
(r.x2 - r.x1) + 1,
|
||||
(r.y2 - r.y1) + 1,
|
||||
stride);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
|
||||
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
|
||||
AGG_INLINE int stride() const { return m_rbuf->stride(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
|
||||
const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
|
||||
row_data row(int y) const { return m_rbuf->row(y); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE int8u* pix_ptr(int x, int y)
|
||||
{
|
||||
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* pix_ptr(int x, int y) const
|
||||
{
|
||||
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
|
||||
}
|
||||
|
||||
// Return pointer to pixel value, forcing row to be allocated.
|
||||
AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
|
||||
{
|
||||
return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
|
||||
}
|
||||
|
||||
// Return pointer to pixel value, or null if row not allocated.
|
||||
AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
|
||||
{
|
||||
int8u* p = m_rbuf->row_ptr(y);
|
||||
return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
|
||||
}
|
||||
|
||||
// Get pixel pointer from raw buffer pointer.
|
||||
AGG_INLINE static pixel_type* pix_value_ptr(void* p)
|
||||
{
|
||||
return (pixel_type*)((value_type*)p + pix_offset);
|
||||
}
|
||||
|
||||
// Get pixel pointer from raw buffer pointer.
|
||||
AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
|
||||
{
|
||||
return (const pixel_type*)((const value_type*)p + pix_offset);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE static void write_plain_color(void* p, color_type c)
|
||||
{
|
||||
// Grayscale formats are implicitly premultiplied.
|
||||
c.premultiply();
|
||||
pix_value_ptr(p)->set(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE static color_type read_plain_color(const void* p)
|
||||
{
|
||||
return pix_value_ptr(p)->get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
|
||||
{
|
||||
((pixel_type*)p)->set(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type pixel(int x, int y) const
|
||||
{
|
||||
if (const pixel_type* p = pix_value_ptr(x, y))
|
||||
{
|
||||
return p->get();
|
||||
}
|
||||
return color_type::no_color();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
pix_value_ptr(x, y, 1)->set(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
do
|
||||
{
|
||||
p->set(c);
|
||||
p = p->next();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
do
|
||||
{
|
||||
pix_value_ptr(x, y++, 1)->set(c);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
if (c.is_opaque() && cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
p->set(c);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
blend_pix(p, c, cover);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
if (c.is_opaque() && cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
pix_value_ptr(x, y++, 1)->set(c);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
blend_pix(pix_value_ptr(x, y++, 1), c, cover);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const int8u* covers)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
do
|
||||
{
|
||||
if (c.is_opaque() && *covers == cover_mask)
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c, *covers);
|
||||
}
|
||||
p = p->next();
|
||||
++covers;
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const int8u* covers)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
do
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y++, 1);
|
||||
|
||||
if (c.is_opaque() && *covers == cover_mask)
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c, *covers);
|
||||
}
|
||||
++covers;
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors)
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
do
|
||||
{
|
||||
p->set(*colors++);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors)
|
||||
{
|
||||
do
|
||||
{
|
||||
pix_value_ptr(x, y++, 1)->set(*colors++);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const int8u* covers,
|
||||
int8u cover)
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
if (covers)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(p, *colors++, *covers++);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(p, *colors++);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(p, *colors++, cover);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const int8u* covers,
|
||||
int8u cover)
|
||||
{
|
||||
if (covers)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Function> void for_each_pixel(Function f)
|
||||
{
|
||||
unsigned y;
|
||||
for (y = 0; y < height(); ++y)
|
||||
{
|
||||
row_data r = m_rbuf->row(y);
|
||||
if (r.ptr)
|
||||
{
|
||||
unsigned len = r.x2 - r.x1 + 1;
|
||||
pixel_type* p = pix_value_ptr(r.x1, y, len);
|
||||
do
|
||||
{
|
||||
f(p->c);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
|
||||
{
|
||||
for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
|
||||
{
|
||||
for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf2>
|
||||
void copy_from(const RenBuf2& from,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len)
|
||||
{
|
||||
if (const int8u* p = from.row_ptr(ysrc))
|
||||
{
|
||||
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
|
||||
p + xsrc * pix_width,
|
||||
len * pix_width);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Blend from single color, using grayscale surface as alpha channel.
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_color(const SrcPixelFormatRenderer& from,
|
||||
const color_type& color,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len,
|
||||
int8u cover)
|
||||
{
|
||||
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
|
||||
typedef typename SrcPixelFormatRenderer::color_type src_color_type;
|
||||
|
||||
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
|
||||
{
|
||||
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
|
||||
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Blend from color table, using grayscale surface as indexes into table.
|
||||
// Obviously, this only works for integer value types.
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_lut(const SrcPixelFormatRenderer& from,
|
||||
const color_type* color_lut,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len,
|
||||
int8u cover)
|
||||
{
|
||||
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
|
||||
|
||||
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
|
||||
{
|
||||
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
|
||||
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
rbuf_type* m_rbuf;
|
||||
};
|
||||
|
||||
typedef blender_gray<gray8> blender_gray8;
|
||||
typedef blender_gray<sgray8> blender_sgray8;
|
||||
typedef blender_gray<gray16> blender_gray16;
|
||||
typedef blender_gray<gray32> blender_gray32;
|
||||
|
||||
typedef blender_gray_pre<gray8> blender_gray8_pre;
|
||||
typedef blender_gray_pre<sgray8> blender_sgray8_pre;
|
||||
typedef blender_gray_pre<gray16> blender_gray16_pre;
|
||||
typedef blender_gray_pre<gray32> blender_gray32_pre;
|
||||
|
||||
typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8;
|
||||
typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8;
|
||||
typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16;
|
||||
typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32;
|
||||
|
||||
typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre;
|
||||
typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre;
|
||||
typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre;
|
||||
typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
995
src/agg/agg_pixfmt_rgb.h
Normal file
995
src/agg/agg_pixfmt_rgb.h
Normal file
|
|
@ -0,0 +1,995 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_RGB_INCLUDED
|
||||
#define AGG_PIXFMT_RGB_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_pixfmt_base.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=====================================================apply_gamma_dir_rgb
|
||||
template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb
|
||||
{
|
||||
public:
|
||||
typedef typename ColorT::value_type value_type;
|
||||
|
||||
apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
|
||||
|
||||
AGG_INLINE void operator () (value_type* p)
|
||||
{
|
||||
p[Order::R] = m_gamma.dir(p[Order::R]);
|
||||
p[Order::G] = m_gamma.dir(p[Order::G]);
|
||||
p[Order::B] = m_gamma.dir(p[Order::B]);
|
||||
}
|
||||
|
||||
private:
|
||||
const GammaLut& m_gamma;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=====================================================apply_gamma_inv_rgb
|
||||
template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb
|
||||
{
|
||||
public:
|
||||
typedef typename ColorT::value_type value_type;
|
||||
|
||||
apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
|
||||
|
||||
AGG_INLINE void operator () (value_type* p)
|
||||
{
|
||||
p[Order::R] = m_gamma.inv(p[Order::R]);
|
||||
p[Order::G] = m_gamma.inv(p[Order::G]);
|
||||
p[Order::B] = m_gamma.inv(p[Order::B]);
|
||||
}
|
||||
|
||||
private:
|
||||
const GammaLut& m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//=========================================================blender_rgb
|
||||
template<class ColorT, class Order>
|
||||
struct blender_rgb
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
// Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
|
||||
// compositing function. Since the render buffer is opaque we skip the
|
||||
// initial premultiply and final demultiply.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha)
|
||||
{
|
||||
p[Order::R] = color_type::lerp(p[Order::R], cr, alpha);
|
||||
p[Order::G] = color_type::lerp(p[Order::G], cg, alpha);
|
||||
p[Order::B] = color_type::lerp(p[Order::B], cb, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
//======================================================blender_rgb_pre
|
||||
template<class ColorT, class Order>
|
||||
struct blender_rgb_pre
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
// Blend pixels using the premultiplied form of Alvy-Ray Smith's
|
||||
// compositing function.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p,
|
||||
color_type::mult_cover(cr, cover),
|
||||
color_type::mult_cover(cg, cover),
|
||||
color_type::mult_cover(cb, cover),
|
||||
color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha)
|
||||
{
|
||||
p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha);
|
||||
p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha);
|
||||
p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
//===================================================blender_rgb_gamma
|
||||
template<class ColorT, class Order, class Gamma>
|
||||
class blender_rgb_gamma : public blender_base<ColorT, Order>
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef Gamma gamma_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
blender_rgb_gamma() : m_gamma(0) {}
|
||||
void gamma(const gamma_type& g) { m_gamma = &g; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha)
|
||||
{
|
||||
calc_type r = m_gamma->dir(p[Order::R]);
|
||||
calc_type g = m_gamma->dir(p[Order::G]);
|
||||
calc_type b = m_gamma->dir(p[Order::B]);
|
||||
p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r);
|
||||
p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g);
|
||||
p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b);
|
||||
}
|
||||
|
||||
private:
|
||||
const gamma_type* m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//==================================================pixfmt_alpha_blend_rgb
|
||||
template<class Blender, class RenBuf, unsigned Step, unsigned Offset = 0>
|
||||
class pixfmt_alpha_blend_rgb
|
||||
{
|
||||
public:
|
||||
typedef pixfmt_rgb_tag pixfmt_category;
|
||||
typedef RenBuf rbuf_type;
|
||||
typedef Blender blender_type;
|
||||
typedef typename rbuf_type::row_data row_data;
|
||||
typedef typename blender_type::color_type color_type;
|
||||
typedef typename blender_type::order_type order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
enum
|
||||
{
|
||||
num_components = 3,
|
||||
pix_step = Step,
|
||||
pix_offset = Offset,
|
||||
pix_width = sizeof(value_type) * pix_step
|
||||
};
|
||||
struct pixel_type
|
||||
{
|
||||
value_type c[num_components];
|
||||
|
||||
void set(value_type r, value_type g, value_type b)
|
||||
{
|
||||
c[order_type::R] = r;
|
||||
c[order_type::G] = g;
|
||||
c[order_type::B] = b;
|
||||
}
|
||||
|
||||
void set(const color_type& color)
|
||||
{
|
||||
set(color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void get(value_type& r, value_type& g, value_type& b) const
|
||||
{
|
||||
r = c[order_type::R];
|
||||
g = c[order_type::G];
|
||||
b = c[order_type::B];
|
||||
}
|
||||
|
||||
color_type get() const
|
||||
{
|
||||
return color_type(
|
||||
c[order_type::R],
|
||||
c[order_type::G],
|
||||
c[order_type::B]);
|
||||
}
|
||||
|
||||
pixel_type* next()
|
||||
{
|
||||
return (pixel_type*)(c + pix_step);
|
||||
}
|
||||
|
||||
const pixel_type* next() const
|
||||
{
|
||||
return (const pixel_type*)(c + pix_step);
|
||||
}
|
||||
|
||||
pixel_type* advance(int n)
|
||||
{
|
||||
return (pixel_type*)(c + n * pix_step);
|
||||
}
|
||||
|
||||
const pixel_type* advance(int n) const
|
||||
{
|
||||
return (const pixel_type*)(c + n * pix_step);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p,
|
||||
value_type r, value_type g, value_type b, value_type a,
|
||||
unsigned cover)
|
||||
{
|
||||
m_blender.blend_pix(p->c, r, g, b, a, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p,
|
||||
value_type r, value_type g, value_type b, value_type a)
|
||||
{
|
||||
m_blender.blend_pix(p->c, r, g, b, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
|
||||
{
|
||||
m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
|
||||
{
|
||||
m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
if (c.is_opaque() && cover == cover_mask)
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c, cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
if (c.is_opaque())
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) :
|
||||
m_rbuf(&rb)
|
||||
{}
|
||||
void attach(rbuf_type& rb) { m_rbuf = &rb; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class PixFmt>
|
||||
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rect_i r(x1, y1, x2, y2);
|
||||
if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
|
||||
{
|
||||
int stride = pixf.stride();
|
||||
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
|
||||
(r.x2 - r.x1) + 1,
|
||||
(r.y2 - r.y1) + 1,
|
||||
stride);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
Blender& blender() { return m_blender; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
|
||||
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
|
||||
AGG_INLINE int stride() const { return m_rbuf->stride(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
|
||||
AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
|
||||
AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE int8u* pix_ptr(int x, int y)
|
||||
{
|
||||
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* pix_ptr(int x, int y) const
|
||||
{
|
||||
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
|
||||
}
|
||||
|
||||
// Return pointer to pixel value, forcing row to be allocated.
|
||||
AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
|
||||
{
|
||||
return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
|
||||
}
|
||||
|
||||
// Return pointer to pixel value, or null if row not allocated.
|
||||
AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
|
||||
{
|
||||
int8u* p = m_rbuf->row_ptr(y);
|
||||
return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
|
||||
}
|
||||
|
||||
// Get pixel pointer from raw buffer pointer.
|
||||
AGG_INLINE static pixel_type* pix_value_ptr(void* p)
|
||||
{
|
||||
return (pixel_type*)((value_type*)p + pix_offset);
|
||||
}
|
||||
|
||||
// Get pixel pointer from raw buffer pointer.
|
||||
AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
|
||||
{
|
||||
return (const pixel_type*)((const value_type*)p + pix_offset);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE static void write_plain_color(void* p, color_type c)
|
||||
{
|
||||
// RGB formats are implicitly premultiplied.
|
||||
c.premultiply();
|
||||
pix_value_ptr(p)->set(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE static color_type read_plain_color(const void* p)
|
||||
{
|
||||
return pix_value_ptr(p)->get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
|
||||
{
|
||||
((pixel_type*)p)->set(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type pixel(int x, int y) const
|
||||
{
|
||||
if (const pixel_type* p = pix_value_ptr(x, y))
|
||||
{
|
||||
return p->get();
|
||||
}
|
||||
return color_type::no_color();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
pix_value_ptr(x, y, 1)->set(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
do
|
||||
{
|
||||
p->set(c);
|
||||
p = p->next();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
do
|
||||
{
|
||||
pix_value_ptr(x, y++, 1)->set(c);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
if (c.is_opaque() && cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
p->set(c);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
blend_pix(p, c, cover);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
if (c.is_opaque() && cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
pix_value_ptr(x, y++, 1)->set(c);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
blend_pix(pix_value_ptr(x, y++, 1), c, cover);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const int8u* covers)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
do
|
||||
{
|
||||
if (c.is_opaque() && *covers == cover_mask)
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c, *covers);
|
||||
}
|
||||
p = p->next();
|
||||
++covers;
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const int8u* covers)
|
||||
{
|
||||
if (!c.is_transparent())
|
||||
{
|
||||
do
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y++, 1);
|
||||
|
||||
if (c.is_opaque() && *covers == cover_mask)
|
||||
{
|
||||
p->set(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(p, c, *covers);
|
||||
}
|
||||
++covers;
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors)
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
do
|
||||
{
|
||||
p->set(*colors++);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors)
|
||||
{
|
||||
do
|
||||
{
|
||||
pix_value_ptr(x, y++, 1)->set(*colors++);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const int8u* covers,
|
||||
int8u cover)
|
||||
{
|
||||
pixel_type* p = pix_value_ptr(x, y, len);
|
||||
|
||||
if (covers)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(p, *colors++, *covers++);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(p, *colors++);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(p, *colors++, cover);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const int8u* covers,
|
||||
int8u cover)
|
||||
{
|
||||
if (covers)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Function> void for_each_pixel(Function f)
|
||||
{
|
||||
for (unsigned y = 0; y < height(); ++y)
|
||||
{
|
||||
row_data r = m_rbuf->row(y);
|
||||
if (r.ptr)
|
||||
{
|
||||
unsigned len = r.x2 - r.x1 + 1;
|
||||
pixel_type* p = pix_value_ptr(r.x1, y, len);
|
||||
do
|
||||
{
|
||||
f(p->c);
|
||||
p = p->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
|
||||
{
|
||||
for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
|
||||
{
|
||||
for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf2>
|
||||
void copy_from(const RenBuf2& from,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len)
|
||||
{
|
||||
if (const int8u* p = from.row_ptr(ysrc))
|
||||
{
|
||||
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
|
||||
p + xsrc * pix_width,
|
||||
len * pix_width);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Blend from an RGBA surface.
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from(const SrcPixelFormatRenderer& from,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len,
|
||||
int8u cover)
|
||||
{
|
||||
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
|
||||
typedef typename SrcPixelFormatRenderer::order_type src_order;
|
||||
|
||||
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
|
||||
{
|
||||
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
|
||||
|
||||
if (cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
value_type alpha = psrc->c[src_order::A];
|
||||
if (alpha <= color_type::empty_value())
|
||||
{
|
||||
if (alpha >= color_type::full_value())
|
||||
{
|
||||
pdst->c[order_type::R] = psrc->c[src_order::R];
|
||||
pdst->c[order_type::G] = psrc->c[src_order::G];
|
||||
pdst->c[order_type::B] = psrc->c[src_order::B];
|
||||
}
|
||||
else
|
||||
{
|
||||
blend_pix(pdst,
|
||||
psrc->c[src_order::R],
|
||||
psrc->c[src_order::G],
|
||||
psrc->c[src_order::B],
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pdst, psrc->get(), cover);
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Blend from single color, using grayscale surface as alpha channel.
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_color(const SrcPixelFormatRenderer& from,
|
||||
const color_type& color,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len,
|
||||
int8u cover)
|
||||
{
|
||||
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
|
||||
typedef typename SrcPixelFormatRenderer::color_type src_color_type;
|
||||
|
||||
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
|
||||
{
|
||||
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
|
||||
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while (--len);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Blend from color table, using grayscale surface as indexes into table.
|
||||
// Obviously, this only works for integer value types.
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_lut(const SrcPixelFormatRenderer& from,
|
||||
const color_type* color_lut,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len,
|
||||
int8u cover)
|
||||
{
|
||||
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
|
||||
|
||||
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
|
||||
{
|
||||
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
|
||||
|
||||
if (cover == cover_mask)
|
||||
{
|
||||
do
|
||||
{
|
||||
const color_type& color = color_lut[psrc->c[0]];
|
||||
blend_pix(pdst, color);
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
|
||||
psrc = psrc->next();
|
||||
pdst = pdst->next();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
rbuf_type* m_rbuf;
|
||||
Blender m_blender;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
typedef blender_rgb<rgba8, order_rgb> blender_rgb24;
|
||||
typedef blender_rgb<rgba8, order_bgr> blender_bgr24;
|
||||
typedef blender_rgb<srgba8, order_rgb> blender_srgb24;
|
||||
typedef blender_rgb<srgba8, order_bgr> blender_sbgr24;
|
||||
typedef blender_rgb<rgba16, order_rgb> blender_rgb48;
|
||||
typedef blender_rgb<rgba16, order_bgr> blender_bgr48;
|
||||
typedef blender_rgb<rgba32, order_rgb> blender_rgb96;
|
||||
typedef blender_rgb<rgba32, order_bgr> blender_bgr96;
|
||||
|
||||
typedef blender_rgb_pre<rgba8, order_rgb> blender_rgb24_pre;
|
||||
typedef blender_rgb_pre<rgba8, order_bgr> blender_bgr24_pre;
|
||||
typedef blender_rgb_pre<srgba8, order_rgb> blender_srgb24_pre;
|
||||
typedef blender_rgb_pre<srgba8, order_bgr> blender_sbgr24_pre;
|
||||
typedef blender_rgb_pre<rgba16, order_rgb> blender_rgb48_pre;
|
||||
typedef blender_rgb_pre<rgba16, order_bgr> blender_bgr48_pre;
|
||||
typedef blender_rgb_pre<rgba32, order_rgb> blender_rgb96_pre;
|
||||
typedef blender_rgb_pre<rgba32, order_bgr> blender_bgr96_pre;
|
||||
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 3> pixfmt_rgb24;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 3> pixfmt_bgr24;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 3> pixfmt_srgb24;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 3> pixfmt_sbgr24;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 3> pixfmt_rgb48;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 3> pixfmt_bgr48;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 3> pixfmt_rgb96;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 3> pixfmt_bgr96;
|
||||
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 3> pixfmt_rgb24_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 3> pixfmt_bgr24_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 3> pixfmt_srgb24_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 3> pixfmt_sbgr24_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 3> pixfmt_rgb48_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 3> pixfmt_bgr48_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 3> pixfmt_rgb96_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 3> pixfmt_bgr96_pre;
|
||||
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 0> pixfmt_rgbx32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 1> pixfmt_xrgb32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 1> pixfmt_xbgr32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 0> pixfmt_bgrx32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 0> pixfmt_srgbx32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 1> pixfmt_sxrgb32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 1> pixfmt_sxbgr32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 0> pixfmt_sbgrx32;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 0> pixfmt_rgbx64;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 1> pixfmt_xrgb64;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 1> pixfmt_xbgr64;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 0> pixfmt_bgrx64;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 0> pixfmt_rgbx128;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 1> pixfmt_xrgb128;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 1> pixfmt_xbgr128;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 0> pixfmt_bgrx128;
|
||||
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 0> pixfmt_rgbx32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 1> pixfmt_xrgb32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 1> pixfmt_xbgr32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 0> pixfmt_bgrx32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 0> pixfmt_srgbx32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 1> pixfmt_sxrgb32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 1> pixfmt_sxbgr32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 0> pixfmt_sbgrx32_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 0> pixfmt_rgbx64_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 1> pixfmt_xrgb64_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 1> pixfmt_xbgr64_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 0> pixfmt_bgrx64_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 0> pixfmt_rgbx128_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 1> pixfmt_xrgb128_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 1> pixfmt_xbgr128_pre;
|
||||
typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 0> pixfmt_bgrx128_pre;
|
||||
|
||||
|
||||
//-----------------------------------------------------pixfmt_rgb24_gamma
|
||||
template<class Gamma> class pixfmt_rgb24_gamma :
|
||||
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>
|
||||
{
|
||||
public:
|
||||
pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
|
||||
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb)
|
||||
{
|
||||
this->blender().gamma(g);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------pixfmt_srgb24_gamma
|
||||
template<class Gamma> class pixfmt_srgb24_gamma :
|
||||
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>
|
||||
{
|
||||
public:
|
||||
pixfmt_srgb24_gamma(rendering_buffer& rb, const Gamma& g) :
|
||||
pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb)
|
||||
{
|
||||
this->blender().gamma(g);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------pixfmt_bgr24_gamma
|
||||
template<class Gamma> class pixfmt_bgr24_gamma :
|
||||
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>
|
||||
{
|
||||
public:
|
||||
pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
|
||||
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb)
|
||||
{
|
||||
this->blender().gamma(g);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------pixfmt_sbgr24_gamma
|
||||
template<class Gamma> class pixfmt_sbgr24_gamma :
|
||||
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>
|
||||
{
|
||||
public:
|
||||
pixfmt_sbgr24_gamma(rendering_buffer& rb, const Gamma& g) :
|
||||
pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb)
|
||||
{
|
||||
this->blender().gamma(g);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------pixfmt_rgb48_gamma
|
||||
template<class Gamma> class pixfmt_rgb48_gamma :
|
||||
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>
|
||||
{
|
||||
public:
|
||||
pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) :
|
||||
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>(rb)
|
||||
{
|
||||
this->blender().gamma(g);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------pixfmt_bgr48_gamma
|
||||
template<class Gamma> class pixfmt_bgr48_gamma :
|
||||
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>
|
||||
{
|
||||
public:
|
||||
pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) :
|
||||
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>(rb)
|
||||
{
|
||||
this->blender().gamma(g);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
741
src/agg/agg_rasterizer_cells_aa.h
Normal file
741
src/agg/agg_rasterizer_cells_aa.h
Normal file
|
|
@ -0,0 +1,741 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// The author gratefully acknowleges the support of David Turner,
|
||||
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
|
||||
// libray - in producing this work. See http://www.freetype.org for details.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
|
||||
#define AGG_RASTERIZER_CELLS_AA_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include "agg_math.h"
|
||||
#include "agg_array.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------rasterizer_cells_aa
|
||||
// An internal class that implements the main rasterization algorithm.
|
||||
// Used in the rasterizer. Should not be used direcly.
|
||||
template<class Cell> class rasterizer_cells_aa
|
||||
{
|
||||
enum cell_block_scale_e
|
||||
{
|
||||
cell_block_shift = 12,
|
||||
cell_block_size = 1 << cell_block_shift,
|
||||
cell_block_mask = cell_block_size - 1,
|
||||
cell_block_pool = 256,
|
||||
cell_block_limit = 1024
|
||||
};
|
||||
|
||||
struct sorted_y
|
||||
{
|
||||
unsigned start;
|
||||
unsigned num;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Cell cell_type;
|
||||
typedef rasterizer_cells_aa<Cell> self_type;
|
||||
|
||||
~rasterizer_cells_aa();
|
||||
rasterizer_cells_aa();
|
||||
|
||||
void reset();
|
||||
void style(const cell_type& style_cell);
|
||||
void line(int x1, int y1, int x2, int y2);
|
||||
|
||||
int min_x() const { return m_min_x; }
|
||||
int min_y() const { return m_min_y; }
|
||||
int max_x() const { return m_max_x; }
|
||||
int max_y() const { return m_max_y; }
|
||||
|
||||
void sort_cells();
|
||||
|
||||
unsigned total_cells() const
|
||||
{
|
||||
return m_num_cells;
|
||||
}
|
||||
|
||||
unsigned scanline_num_cells(unsigned y) const
|
||||
{
|
||||
return m_sorted_y[y - m_min_y].num;
|
||||
}
|
||||
|
||||
const cell_type* const* scanline_cells(unsigned y) const
|
||||
{
|
||||
return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start;
|
||||
}
|
||||
|
||||
bool sorted() const { return m_sorted; }
|
||||
|
||||
private:
|
||||
rasterizer_cells_aa(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
void set_curr_cell(int x, int y);
|
||||
void add_curr_cell();
|
||||
void render_hline(int ey, int x1, int y1, int x2, int y2);
|
||||
void allocate_block();
|
||||
|
||||
private:
|
||||
unsigned m_num_blocks;
|
||||
unsigned m_max_blocks;
|
||||
unsigned m_curr_block;
|
||||
unsigned m_num_cells;
|
||||
cell_type** m_cells;
|
||||
cell_type* m_curr_cell_ptr;
|
||||
pod_vector<cell_type*> m_sorted_cells;
|
||||
pod_vector<sorted_y> m_sorted_y;
|
||||
cell_type m_curr_cell;
|
||||
cell_type m_style_cell;
|
||||
int m_min_x;
|
||||
int m_min_y;
|
||||
int m_max_x;
|
||||
int m_max_y;
|
||||
bool m_sorted;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
rasterizer_cells_aa<Cell>::~rasterizer_cells_aa()
|
||||
{
|
||||
if(m_num_blocks)
|
||||
{
|
||||
cell_type** ptr = m_cells + m_num_blocks - 1;
|
||||
while(m_num_blocks--)
|
||||
{
|
||||
pod_allocator<cell_type>::deallocate(*ptr, cell_block_size);
|
||||
ptr--;
|
||||
}
|
||||
pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
rasterizer_cells_aa<Cell>::rasterizer_cells_aa() :
|
||||
m_num_blocks(0),
|
||||
m_max_blocks(0),
|
||||
m_curr_block(0),
|
||||
m_num_cells(0),
|
||||
m_cells(0),
|
||||
m_curr_cell_ptr(0),
|
||||
m_sorted_cells(),
|
||||
m_sorted_y(),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min()),
|
||||
m_sorted(false)
|
||||
{
|
||||
m_style_cell.initial();
|
||||
m_curr_cell.initial();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void rasterizer_cells_aa<Cell>::reset()
|
||||
{
|
||||
m_num_cells = 0;
|
||||
m_curr_block = 0;
|
||||
m_curr_cell.initial();
|
||||
m_style_cell.initial();
|
||||
m_sorted = false;
|
||||
m_min_x = std::numeric_limits<int>::max();
|
||||
m_min_y = std::numeric_limits<int>::max();
|
||||
m_max_x = std::numeric_limits<int>::min();
|
||||
m_max_y = std::numeric_limits<int>::min();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell()
|
||||
{
|
||||
if(m_curr_cell.area | m_curr_cell.cover)
|
||||
{
|
||||
if((m_num_cells & cell_block_mask) == 0)
|
||||
{
|
||||
if(m_num_blocks >= cell_block_limit) return;
|
||||
allocate_block();
|
||||
}
|
||||
*m_curr_cell_ptr++ = m_curr_cell;
|
||||
++m_num_cells;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y)
|
||||
{
|
||||
if(m_curr_cell.not_equal(x, y, m_style_cell))
|
||||
{
|
||||
add_curr_cell();
|
||||
m_curr_cell.style(m_style_cell);
|
||||
m_curr_cell.x = x;
|
||||
m_curr_cell.y = y;
|
||||
m_curr_cell.cover = 0;
|
||||
m_curr_cell.area = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey,
|
||||
int x1, int y1,
|
||||
int x2, int y2)
|
||||
{
|
||||
int ex1 = x1 >> poly_subpixel_shift;
|
||||
int ex2 = x2 >> poly_subpixel_shift;
|
||||
int fx1 = x1 & poly_subpixel_mask;
|
||||
int fx2 = x2 & poly_subpixel_mask;
|
||||
|
||||
int delta, p, first;
|
||||
long long dx;
|
||||
int incr, lift, mod, rem;
|
||||
|
||||
//trivial case. Happens often
|
||||
if(y1 == y2)
|
||||
{
|
||||
set_curr_cell(ex2, ey);
|
||||
return;
|
||||
}
|
||||
|
||||
//everything is located in a single cell. That is easy!
|
||||
if(ex1 == ex2)
|
||||
{
|
||||
delta = y2 - y1;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += (fx1 + fx2) * delta;
|
||||
return;
|
||||
}
|
||||
|
||||
//ok, we'll have to render a run of adjacent cells on the same
|
||||
//hline...
|
||||
p = (poly_subpixel_scale - fx1) * (y2 - y1);
|
||||
first = poly_subpixel_scale;
|
||||
incr = 1;
|
||||
|
||||
dx = (long long)x2 - (long long)x1;
|
||||
|
||||
if(dx < 0)
|
||||
{
|
||||
p = fx1 * (y2 - y1);
|
||||
first = 0;
|
||||
incr = -1;
|
||||
dx = -dx;
|
||||
}
|
||||
|
||||
delta = (int)(p / dx);
|
||||
mod = (int)(p % dx);
|
||||
|
||||
if(mod < 0)
|
||||
{
|
||||
delta--;
|
||||
mod += static_cast<int>(dx);
|
||||
}
|
||||
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += (fx1 + first) * delta;
|
||||
|
||||
ex1 += incr;
|
||||
set_curr_cell(ex1, ey);
|
||||
y1 += delta;
|
||||
|
||||
if(ex1 != ex2)
|
||||
{
|
||||
p = poly_subpixel_scale * (y2 - y1 + delta);
|
||||
lift = (int)(p / dx);
|
||||
rem = (int)(p % dx);
|
||||
|
||||
if (rem < 0)
|
||||
{
|
||||
lift--;
|
||||
rem += static_cast<int>(dx);
|
||||
}
|
||||
|
||||
mod -= static_cast<int>(dx);
|
||||
|
||||
while (ex1 != ex2)
|
||||
{
|
||||
delta = lift;
|
||||
mod += rem;
|
||||
if(mod >= 0)
|
||||
{
|
||||
mod -= static_cast<int>(dx);
|
||||
delta++;
|
||||
}
|
||||
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += poly_subpixel_scale * delta;
|
||||
y1 += delta;
|
||||
ex1 += incr;
|
||||
set_curr_cell(ex1, ey);
|
||||
}
|
||||
}
|
||||
delta = y2 - y1;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell)
|
||||
{
|
||||
m_style_cell.style(style_cell);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
|
||||
|
||||
long long dx = (long long)x2 - (long long)x1;
|
||||
|
||||
if(dx >= dx_limit || dx <= -dx_limit)
|
||||
{
|
||||
int cx = (int)(((long long)x1 + (long long)x2) >> 1);
|
||||
int cy = (int)(((long long)y1 + (long long)y2) >> 1);
|
||||
line(x1, y1, cx, cy);
|
||||
line(cx, cy, x2, y2);
|
||||
}
|
||||
|
||||
long long dy = (long long)y2 - (long long)y1;
|
||||
int ex1 = x1 >> poly_subpixel_shift;
|
||||
int ex2 = x2 >> poly_subpixel_shift;
|
||||
int ey1 = y1 >> poly_subpixel_shift;
|
||||
int ey2 = y2 >> poly_subpixel_shift;
|
||||
int fy1 = y1 & poly_subpixel_mask;
|
||||
int fy2 = y2 & poly_subpixel_mask;
|
||||
|
||||
int x_from, x_to;
|
||||
int rem, mod, lift, delta, first, incr;
|
||||
long long p;
|
||||
|
||||
if(ex1 < m_min_x) m_min_x = ex1;
|
||||
if(ex1 > m_max_x) m_max_x = ex1;
|
||||
if(ey1 < m_min_y) m_min_y = ey1;
|
||||
if(ey1 > m_max_y) m_max_y = ey1;
|
||||
if(ex2 < m_min_x) m_min_x = ex2;
|
||||
if(ex2 > m_max_x) m_max_x = ex2;
|
||||
if(ey2 < m_min_y) m_min_y = ey2;
|
||||
if(ey2 > m_max_y) m_max_y = ey2;
|
||||
|
||||
set_curr_cell(ex1, ey1);
|
||||
|
||||
//everything is on a single hline
|
||||
if(ey1 == ey2)
|
||||
{
|
||||
render_hline(ey1, x1, fy1, x2, fy2);
|
||||
return;
|
||||
}
|
||||
|
||||
//Vertical line - we have to calculate start and end cells,
|
||||
//and then - the common values of the area and coverage for
|
||||
//all cells of the line. We know exactly there's only one
|
||||
//cell, so, we don't have to call render_hline().
|
||||
incr = 1;
|
||||
if(dx == 0)
|
||||
{
|
||||
int ex = x1 >> poly_subpixel_shift;
|
||||
int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
|
||||
int area;
|
||||
|
||||
first = poly_subpixel_scale;
|
||||
if(dy < 0)
|
||||
{
|
||||
first = 0;
|
||||
incr = -1;
|
||||
}
|
||||
|
||||
x_from = x1;
|
||||
|
||||
//render_hline(ey1, x_from, fy1, x_from, first);
|
||||
delta = first - fy1;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += two_fx * delta;
|
||||
|
||||
ey1 += incr;
|
||||
set_curr_cell(ex, ey1);
|
||||
|
||||
delta = first + first - poly_subpixel_scale;
|
||||
area = two_fx * delta;
|
||||
while(ey1 != ey2)
|
||||
{
|
||||
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first);
|
||||
m_curr_cell.cover = delta;
|
||||
m_curr_cell.area = area;
|
||||
ey1 += incr;
|
||||
set_curr_cell(ex, ey1);
|
||||
}
|
||||
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2);
|
||||
delta = fy2 - poly_subpixel_scale + first;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += two_fx * delta;
|
||||
return;
|
||||
}
|
||||
|
||||
//ok, we have to render several hlines
|
||||
p = (poly_subpixel_scale - fy1) * dx;
|
||||
first = poly_subpixel_scale;
|
||||
|
||||
if(dy < 0)
|
||||
{
|
||||
p = fy1 * dx;
|
||||
first = 0;
|
||||
incr = -1;
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
delta = (int)(p / dy);
|
||||
mod = (int)(p % dy);
|
||||
|
||||
if(mod < 0)
|
||||
{
|
||||
delta--;
|
||||
mod += static_cast<int>(dy);
|
||||
}
|
||||
|
||||
x_from = x1 + delta;
|
||||
render_hline(ey1, x1, fy1, x_from, first);
|
||||
|
||||
ey1 += incr;
|
||||
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
|
||||
|
||||
if(ey1 != ey2)
|
||||
{
|
||||
p = poly_subpixel_scale * dx;
|
||||
lift = (int)(p / dy);
|
||||
rem = (int)(p % dy);
|
||||
|
||||
if(rem < 0)
|
||||
{
|
||||
lift--;
|
||||
rem += static_cast<int>(dy);
|
||||
}
|
||||
mod -= static_cast<int>(dy);
|
||||
|
||||
while(ey1 != ey2)
|
||||
{
|
||||
delta = lift;
|
||||
mod += rem;
|
||||
if (mod >= 0)
|
||||
{
|
||||
mod -= static_cast<int>(dy);
|
||||
delta++;
|
||||
}
|
||||
|
||||
x_to = x_from + delta;
|
||||
render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first);
|
||||
x_from = x_to;
|
||||
|
||||
ey1 += incr;
|
||||
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
|
||||
}
|
||||
}
|
||||
render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void rasterizer_cells_aa<Cell>::allocate_block()
|
||||
{
|
||||
if(m_curr_block >= m_num_blocks)
|
||||
{
|
||||
if(m_num_blocks >= m_max_blocks)
|
||||
{
|
||||
cell_type** new_cells =
|
||||
pod_allocator<cell_type*>::allocate(m_max_blocks +
|
||||
cell_block_pool);
|
||||
|
||||
if(m_cells)
|
||||
{
|
||||
memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*));
|
||||
pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
|
||||
}
|
||||
m_cells = new_cells;
|
||||
m_max_blocks += cell_block_pool;
|
||||
}
|
||||
|
||||
m_cells[m_num_blocks++] =
|
||||
pod_allocator<cell_type>::allocate(cell_block_size);
|
||||
|
||||
}
|
||||
m_curr_cell_ptr = m_cells[m_curr_block++];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class T> static AGG_INLINE void swap_cells(T* a, T* b)
|
||||
{
|
||||
T temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
qsort_threshold = 9
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void qsort_cells(Cell** start, unsigned num)
|
||||
{
|
||||
Cell** stack[80];
|
||||
Cell*** top;
|
||||
Cell** limit;
|
||||
Cell** base;
|
||||
|
||||
limit = start + num;
|
||||
base = start;
|
||||
top = stack;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int len = int(limit - base);
|
||||
|
||||
Cell** i;
|
||||
Cell** j;
|
||||
Cell** pivot;
|
||||
|
||||
if(len > qsort_threshold)
|
||||
{
|
||||
// we use base + len/2 as the pivot
|
||||
pivot = base + len / 2;
|
||||
swap_cells(base, pivot);
|
||||
|
||||
i = base + 1;
|
||||
j = limit - 1;
|
||||
|
||||
// now ensure that *i <= *base <= *j
|
||||
if((*j)->x < (*i)->x)
|
||||
{
|
||||
swap_cells(i, j);
|
||||
}
|
||||
|
||||
if((*base)->x < (*i)->x)
|
||||
{
|
||||
swap_cells(base, i);
|
||||
}
|
||||
|
||||
if((*j)->x < (*base)->x)
|
||||
{
|
||||
swap_cells(base, j);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int x = (*base)->x;
|
||||
do i++; while( (*i)->x < x );
|
||||
do j--; while( x < (*j)->x );
|
||||
|
||||
if(i > j)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
swap_cells(i, j);
|
||||
}
|
||||
|
||||
swap_cells(base, j);
|
||||
|
||||
// now, push the largest sub-array
|
||||
if(j - base > limit - i)
|
||||
{
|
||||
top[0] = base;
|
||||
top[1] = j;
|
||||
base = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
top[0] = i;
|
||||
top[1] = limit;
|
||||
limit = j;
|
||||
}
|
||||
top += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the sub-array is small, perform insertion sort
|
||||
j = base;
|
||||
i = j + 1;
|
||||
|
||||
for(; i < limit; j = i, i++)
|
||||
{
|
||||
for(; j[1]->x < (*j)->x; j--)
|
||||
{
|
||||
swap_cells(j + 1, j);
|
||||
if (j == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(top > stack)
|
||||
{
|
||||
top -= 2;
|
||||
base = top[0];
|
||||
limit = top[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void rasterizer_cells_aa<Cell>::sort_cells()
|
||||
{
|
||||
if(m_sorted) return; //Perform sort only the first time.
|
||||
|
||||
add_curr_cell();
|
||||
m_curr_cell.x = std::numeric_limits<int>::max();
|
||||
m_curr_cell.y = std::numeric_limits<int>::max();
|
||||
m_curr_cell.cover = 0;
|
||||
m_curr_cell.area = 0;
|
||||
|
||||
if(m_num_cells == 0) return;
|
||||
|
||||
// DBG: Check to see if min/max works well.
|
||||
//for(unsigned nc = 0; nc < m_num_cells; nc++)
|
||||
//{
|
||||
// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask);
|
||||
// if(cell->x < m_min_x ||
|
||||
// cell->y < m_min_y ||
|
||||
// cell->x > m_max_x ||
|
||||
// cell->y > m_max_y)
|
||||
// {
|
||||
// cell = cell; // Breakpoint here
|
||||
// }
|
||||
//}
|
||||
// Allocate the array of cell pointers
|
||||
m_sorted_cells.allocate(m_num_cells, 16);
|
||||
|
||||
// Allocate and zero the Y array
|
||||
m_sorted_y.allocate(m_max_y - m_min_y + 1, 16);
|
||||
m_sorted_y.zero();
|
||||
|
||||
// Create the Y-histogram (count the numbers of cells for each Y)
|
||||
cell_type** block_ptr = m_cells;
|
||||
cell_type* cell_ptr;
|
||||
unsigned nb = m_num_cells;
|
||||
unsigned i;
|
||||
while(nb)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
|
||||
nb -= i;
|
||||
while(i--)
|
||||
{
|
||||
m_sorted_y[cell_ptr->y - m_min_y].start++;
|
||||
++cell_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the Y-histogram into the array of starting indexes
|
||||
unsigned start = 0;
|
||||
for(i = 0; i < m_sorted_y.size(); i++)
|
||||
{
|
||||
unsigned v = m_sorted_y[i].start;
|
||||
m_sorted_y[i].start = start;
|
||||
start += v;
|
||||
}
|
||||
|
||||
// Fill the cell pointer array sorted by Y
|
||||
block_ptr = m_cells;
|
||||
nb = m_num_cells;
|
||||
while(nb)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
|
||||
nb -= i;
|
||||
while(i--)
|
||||
{
|
||||
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
|
||||
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
|
||||
++curr_y.num;
|
||||
++cell_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally arrange the X-arrays
|
||||
for(i = 0; i < m_sorted_y.size(); i++)
|
||||
{
|
||||
const sorted_y& curr_y = m_sorted_y[i];
|
||||
if(curr_y.num)
|
||||
{
|
||||
qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num);
|
||||
}
|
||||
}
|
||||
m_sorted = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------scanline_hit_test
|
||||
class scanline_hit_test
|
||||
{
|
||||
public:
|
||||
scanline_hit_test(int x) : m_x(x), m_hit(false) {}
|
||||
|
||||
void reset_spans() {}
|
||||
void finalize(int) {}
|
||||
void add_cell(int x, int)
|
||||
{
|
||||
if(m_x == x) m_hit = true;
|
||||
}
|
||||
void add_span(int x, int len, int)
|
||||
{
|
||||
if(m_x >= x && m_x < x+len) m_hit = true;
|
||||
}
|
||||
unsigned num_spans() const { return 1; }
|
||||
bool hit() const { return m_hit; }
|
||||
|
||||
private:
|
||||
int m_x;
|
||||
bool m_hit;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
481
src/agg/agg_rasterizer_scanline_aa.h
Normal file
481
src/agg/agg_rasterizer_scanline_aa.h
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// The author gratefully acknowleges the support of David Turner,
|
||||
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
|
||||
// libray - in producing this work. See http://www.freetype.org for details.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
|
||||
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
|
||||
|
||||
#include "agg_rasterizer_cells_aa.h"
|
||||
#include "agg_rasterizer_sl_clip.h"
|
||||
#include "agg_rasterizer_scanline_aa_nogamma.h"
|
||||
#include "agg_gamma_functions.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//==================================================rasterizer_scanline_aa
|
||||
// Polygon rasterizer that is used to render filled polygons with
|
||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
||||
// used in the following way:
|
||||
//
|
||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
||||
//
|
||||
// 2. gamma() - optional.
|
||||
//
|
||||
// 3. reset()
|
||||
//
|
||||
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
|
||||
// more than one contour, but each contour must consist of at least 3
|
||||
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
|
||||
// is the absolute minimum of vertices that define a triangle.
|
||||
// The algorithm does not check either the number of vertices nor
|
||||
// coincidence of their coordinates, but in the worst case it just
|
||||
// won't draw anything.
|
||||
// The orger of the vertices (clockwise or counterclockwise)
|
||||
// is important when using the non-zero filling rule (fill_non_zero).
|
||||
// In this case the vertex order of all the contours must be the same
|
||||
// if you want your intersecting polygons to be without "holes".
|
||||
// You actually can use different vertices order. If the contours do not
|
||||
// intersect each other the order is not important anyway. If they do,
|
||||
// contours with the same vertex order will be rendered without "holes"
|
||||
// while the intersecting contours with different orders will have "holes".
|
||||
//
|
||||
// filling_rule() and gamma() can be called anytime before "sweeping".
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
|
||||
{
|
||||
enum status
|
||||
{
|
||||
status_initial,
|
||||
status_move_to,
|
||||
status_line_to,
|
||||
status_closed
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Clip clip_type;
|
||||
typedef typename Clip::conv_type conv_type;
|
||||
typedef typename Clip::coord_type coord_type;
|
||||
|
||||
enum aa_scale_e
|
||||
{
|
||||
aa_shift = 8,
|
||||
aa_scale = 1 << aa_shift,
|
||||
aa_mask = aa_scale - 1,
|
||||
aa_scale2 = aa_scale * 2,
|
||||
aa_mask2 = aa_scale2 - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_scanline_aa() :
|
||||
m_outline(),
|
||||
m_clipper(),
|
||||
m_filling_rule(fill_non_zero),
|
||||
m_auto_close(true),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_status(status_initial)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaF>
|
||||
rasterizer_scanline_aa(const GammaF& gamma_function) :
|
||||
m_outline(),
|
||||
m_clipper(m_outline),
|
||||
m_filling_rule(fill_non_zero),
|
||||
m_auto_close(true),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_status(status_initial)
|
||||
{
|
||||
gamma(gamma_function);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset();
|
||||
void reset_clipping();
|
||||
void clip_box(double x1, double y1, double x2, double y2);
|
||||
void filling_rule(filling_rule_e filling_rule);
|
||||
void auto_close(bool flag) { m_auto_close = flag; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaF> void gamma(const GammaF& gamma_function)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < aa_scale; i++)
|
||||
{
|
||||
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned apply_gamma(unsigned cover) const
|
||||
{
|
||||
return m_gamma[cover];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y);
|
||||
void line_to(int x, int y);
|
||||
void move_to_d(double x, double y);
|
||||
void line_to_d(double x, double y);
|
||||
void close_polygon();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
void edge(int x1, int y1, int x2, int y2);
|
||||
void edge_d(double x1, double y1, double x2, double y2);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
if(m_outline.sorted()) reset();
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int min_x() const { return m_outline.min_x(); }
|
||||
int min_y() const { return m_outline.min_y(); }
|
||||
int max_x() const { return m_outline.max_x(); }
|
||||
int max_y() const { return m_outline.max_y(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void sort();
|
||||
bool rewind_scanlines();
|
||||
bool navigate_scanline(int y);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned calculate_alpha(int area) const
|
||||
{
|
||||
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
|
||||
|
||||
if(cover < 0) cover = -cover;
|
||||
if(m_filling_rule == fill_even_odd)
|
||||
{
|
||||
cover &= aa_mask2;
|
||||
if(cover > aa_scale)
|
||||
{
|
||||
cover = aa_scale2 - cover;
|
||||
}
|
||||
}
|
||||
if(cover > aa_mask) cover = aa_mask;
|
||||
return m_gamma[cover];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(m_scan_y > m_outline.max_y()) return false;
|
||||
sl.reset_spans();
|
||||
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
|
||||
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
|
||||
int cover = 0;
|
||||
|
||||
while(num_cells)
|
||||
{
|
||||
const cell_aa* cur_cell = *cells;
|
||||
int x = cur_cell->x;
|
||||
int area = cur_cell->area;
|
||||
unsigned alpha;
|
||||
|
||||
cover += cur_cell->cover;
|
||||
|
||||
//accumulate all cells with the same X
|
||||
while(--num_cells)
|
||||
{
|
||||
cur_cell = *++cells;
|
||||
if(cur_cell->x != x) break;
|
||||
area += cur_cell->area;
|
||||
cover += cur_cell->cover;
|
||||
}
|
||||
|
||||
if(area)
|
||||
{
|
||||
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_cell(x, alpha);
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
if(num_cells && cur_cell->x > x)
|
||||
{
|
||||
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_span(x, cur_cell->x - x, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sl.num_spans()) break;
|
||||
++m_scan_y;
|
||||
}
|
||||
|
||||
sl.finalize(m_scan_y);
|
||||
++m_scan_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool hit_test(int tx, int ty);
|
||||
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
// Disable copying
|
||||
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
|
||||
const rasterizer_scanline_aa<Clip>&
|
||||
operator = (const rasterizer_scanline_aa<Clip>&);
|
||||
|
||||
private:
|
||||
rasterizer_cells_aa<cell_aa> m_outline;
|
||||
clip_type m_clipper;
|
||||
int m_gamma[aa_scale];
|
||||
filling_rule_e m_filling_rule;
|
||||
bool m_auto_close;
|
||||
coord_type m_start_x;
|
||||
coord_type m_start_y;
|
||||
unsigned m_status;
|
||||
int m_scan_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::reset()
|
||||
{
|
||||
m_outline.reset();
|
||||
m_status = status_initial;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
|
||||
{
|
||||
m_filling_rule = filling_rule;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
reset();
|
||||
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
|
||||
conv_type::upscale(x2), conv_type::upscale(y2));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::reset_clipping()
|
||||
{
|
||||
reset();
|
||||
m_clipper.reset_clipping();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::close_polygon()
|
||||
{
|
||||
if(m_status == status_line_to)
|
||||
{
|
||||
m_clipper.line_to(m_outline, m_start_x, m_start_y);
|
||||
m_status = status_closed;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
if(m_auto_close) close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::downscale(x),
|
||||
m_start_y = conv_type::downscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x),
|
||||
conv_type::downscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
if(m_auto_close) close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::upscale(x),
|
||||
m_start_y = conv_type::upscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x),
|
||||
conv_type::upscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
line_to_d(x, y);
|
||||
}
|
||||
else
|
||||
if(is_close(cmd))
|
||||
{
|
||||
close_polygon();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x2),
|
||||
conv_type::downscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x2),
|
||||
conv_type::upscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::sort()
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = m_outline.min_y();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0 ||
|
||||
y < m_outline.min_y() ||
|
||||
y > m_outline.max_y())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
|
||||
{
|
||||
if(!navigate_scanline(ty)) return false;
|
||||
scanline_hit_test sl(tx);
|
||||
sweep_scanline(sl);
|
||||
return sl.hit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
483
src/agg/agg_rasterizer_scanline_aa_nogamma.h
Normal file
483
src/agg/agg_rasterizer_scanline_aa_nogamma.h
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// The author gratefully acknowleges the support of David Turner,
|
||||
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
|
||||
// libray - in producing this work. See http://www.freetype.org for details.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
|
||||
#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
|
||||
|
||||
#include <limits>
|
||||
#include "agg_rasterizer_cells_aa.h"
|
||||
#include "agg_rasterizer_sl_clip.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
|
||||
//-----------------------------------------------------------------cell_aa
|
||||
// A pixel cell. There're no constructors defined and it was done
|
||||
// intentionally in order to avoid extra overhead when allocating an
|
||||
// array of cells.
|
||||
struct cell_aa
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int cover;
|
||||
int area;
|
||||
|
||||
void initial()
|
||||
{
|
||||
x = std::numeric_limits<int>::max();
|
||||
y = std::numeric_limits<int>::max();
|
||||
cover = 0;
|
||||
area = 0;
|
||||
}
|
||||
|
||||
void style(const cell_aa&) {}
|
||||
|
||||
int not_equal(int ex, int ey, const cell_aa&) const
|
||||
{
|
||||
return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==================================================rasterizer_scanline_aa_nogamma
|
||||
// Polygon rasterizer that is used to render filled polygons with
|
||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
||||
// used in the following way:
|
||||
//
|
||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
||||
//
|
||||
// 2. gamma() - optional.
|
||||
//
|
||||
// 3. reset()
|
||||
//
|
||||
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
|
||||
// more than one contour, but each contour must consist of at least 3
|
||||
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
|
||||
// is the absolute minimum of vertices that define a triangle.
|
||||
// The algorithm does not check either the number of vertices nor
|
||||
// coincidence of their coordinates, but in the worst case it just
|
||||
// won't draw anything.
|
||||
// The orger of the vertices (clockwise or counterclockwise)
|
||||
// is important when using the non-zero filling rule (fill_non_zero).
|
||||
// In this case the vertex order of all the contours must be the same
|
||||
// if you want your intersecting polygons to be without "holes".
|
||||
// You actually can use different vertices order. If the contours do not
|
||||
// intersect each other the order is not important anyway. If they do,
|
||||
// contours with the same vertex order will be rendered without "holes"
|
||||
// while the intersecting contours with different orders will have "holes".
|
||||
//
|
||||
// filling_rule() and gamma() can be called anytime before "sweeping".
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma
|
||||
{
|
||||
enum status
|
||||
{
|
||||
status_initial,
|
||||
status_move_to,
|
||||
status_line_to,
|
||||
status_closed
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Clip clip_type;
|
||||
typedef typename Clip::conv_type conv_type;
|
||||
typedef typename Clip::coord_type coord_type;
|
||||
|
||||
enum aa_scale_e
|
||||
{
|
||||
aa_shift = 8,
|
||||
aa_scale = 1 << aa_shift,
|
||||
aa_mask = aa_scale - 1,
|
||||
aa_scale2 = aa_scale * 2,
|
||||
aa_mask2 = aa_scale2 - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_scanline_aa_nogamma() :
|
||||
m_outline(),
|
||||
m_clipper(),
|
||||
m_filling_rule(fill_non_zero),
|
||||
m_auto_close(true),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_status(status_initial)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset();
|
||||
void reset_clipping();
|
||||
void clip_box(double x1, double y1, double x2, double y2);
|
||||
void filling_rule(filling_rule_e filling_rule);
|
||||
void auto_close(bool flag) { m_auto_close = flag; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned apply_gamma(unsigned cover) const
|
||||
{
|
||||
return cover;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y);
|
||||
void line_to(int x, int y);
|
||||
void move_to_d(double x, double y);
|
||||
void line_to_d(double x, double y);
|
||||
void close_polygon();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
void edge(int x1, int y1, int x2, int y2);
|
||||
void edge_d(double x1, double y1, double x2, double y2);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
if(m_outline.sorted()) reset();
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int min_x() const { return m_outline.min_x(); }
|
||||
int min_y() const { return m_outline.min_y(); }
|
||||
int max_x() const { return m_outline.max_x(); }
|
||||
int max_y() const { return m_outline.max_y(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void sort();
|
||||
bool rewind_scanlines();
|
||||
bool navigate_scanline(int y);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned calculate_alpha(int area) const
|
||||
{
|
||||
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
|
||||
|
||||
if(cover < 0) cover = -cover;
|
||||
if(m_filling_rule == fill_even_odd)
|
||||
{
|
||||
cover &= aa_mask2;
|
||||
if(cover > aa_scale)
|
||||
{
|
||||
cover = aa_scale2 - cover;
|
||||
}
|
||||
}
|
||||
if(cover > aa_mask) cover = aa_mask;
|
||||
return cover;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(m_scan_y > m_outline.max_y()) return false;
|
||||
sl.reset_spans();
|
||||
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
|
||||
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
|
||||
int cover = 0;
|
||||
|
||||
while(num_cells)
|
||||
{
|
||||
const cell_aa* cur_cell = *cells;
|
||||
int x = cur_cell->x;
|
||||
int area = cur_cell->area;
|
||||
unsigned alpha;
|
||||
|
||||
cover += cur_cell->cover;
|
||||
|
||||
//accumulate all cells with the same X
|
||||
while(--num_cells)
|
||||
{
|
||||
cur_cell = *++cells;
|
||||
if(cur_cell->x != x) break;
|
||||
area += cur_cell->area;
|
||||
cover += cur_cell->cover;
|
||||
}
|
||||
|
||||
if(area)
|
||||
{
|
||||
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_cell(x, alpha);
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
if(num_cells && cur_cell->x > x)
|
||||
{
|
||||
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_span(x, cur_cell->x - x, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sl.num_spans()) break;
|
||||
++m_scan_y;
|
||||
}
|
||||
|
||||
sl.finalize(m_scan_y);
|
||||
++m_scan_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool hit_test(int tx, int ty);
|
||||
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
// Disable copying
|
||||
rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma<Clip>&);
|
||||
const rasterizer_scanline_aa_nogamma<Clip>&
|
||||
operator = (const rasterizer_scanline_aa_nogamma<Clip>&);
|
||||
|
||||
private:
|
||||
rasterizer_cells_aa<cell_aa> m_outline;
|
||||
clip_type m_clipper;
|
||||
filling_rule_e m_filling_rule;
|
||||
bool m_auto_close;
|
||||
coord_type m_start_x;
|
||||
coord_type m_start_y;
|
||||
unsigned m_status;
|
||||
int m_scan_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::reset()
|
||||
{
|
||||
m_outline.reset();
|
||||
m_status = status_initial;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::filling_rule(filling_rule_e filling_rule)
|
||||
{
|
||||
m_filling_rule = filling_rule;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::clip_box(double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
reset();
|
||||
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
|
||||
conv_type::upscale(x2), conv_type::upscale(y2));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::reset_clipping()
|
||||
{
|
||||
reset();
|
||||
m_clipper.reset_clipping();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::close_polygon()
|
||||
{
|
||||
if(m_status == status_line_to)
|
||||
{
|
||||
m_clipper.line_to(m_outline, m_start_x, m_start_y);
|
||||
m_status = status_closed;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::move_to(int x, int y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
if(m_auto_close) close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::downscale(x),
|
||||
m_start_y = conv_type::downscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::line_to(int x, int y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x),
|
||||
conv_type::downscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::move_to_d(double x, double y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
if(m_auto_close) close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::upscale(x),
|
||||
m_start_y = conv_type::upscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::line_to_d(double x, double y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x),
|
||||
conv_type::upscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
line_to_d(x, y);
|
||||
}
|
||||
else
|
||||
if(is_close(cmd))
|
||||
{
|
||||
close_polygon();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::edge(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x2),
|
||||
conv_type::downscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::edge_d(double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x2),
|
||||
conv_type::upscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa_nogamma<Clip>::sort()
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::rewind_scanlines()
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = m_outline.min_y();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::navigate_scanline(int y)
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0 ||
|
||||
y < m_outline.min_y() ||
|
||||
y > m_outline.max_y())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
bool rasterizer_scanline_aa_nogamma<Clip>::hit_test(int tx, int ty)
|
||||
{
|
||||
if(!navigate_scanline(ty)) return false;
|
||||
scanline_hit_test sl(tx);
|
||||
sweep_scanline(sl);
|
||||
return sl.hit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
351
src/agg/agg_rasterizer_sl_clip.h
Normal file
351
src/agg/agg_rasterizer_sl_clip.h
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
|
||||
#define AGG_RASTERIZER_SL_CLIP_INCLUDED
|
||||
|
||||
#include "agg_clip_liang_barsky.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//--------------------------------------------------------poly_max_coord_e
|
||||
enum poly_max_coord_e
|
||||
{
|
||||
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
|
||||
};
|
||||
|
||||
//------------------------------------------------------------ras_conv_int
|
||||
struct ras_conv_int
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_int_sat
|
||||
struct ras_conv_int_sat
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v)
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
|
||||
}
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------ras_conv_int_3x
|
||||
struct ras_conv_int_3x
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v * 3; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------ras_conv_dbl
|
||||
struct ras_conv_dbl
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c)
|
||||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_dbl_3x
|
||||
struct ras_conv_dbl_3x
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c)
|
||||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------rasterizer_sl_clip
|
||||
template<class Conv> class rasterizer_sl_clip
|
||||
{
|
||||
public:
|
||||
typedef Conv conv_type;
|
||||
typedef typename Conv::coord_type coord_type;
|
||||
typedef rect_base<coord_type> rect_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_sl_clip() :
|
||||
m_clip_box(0,0,0,0),
|
||||
m_x1(0),
|
||||
m_y1(0),
|
||||
m_f1(0),
|
||||
m_clipping(false)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping()
|
||||
{
|
||||
m_clipping = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
|
||||
{
|
||||
m_clip_box = rect_type(x1, y1, x2, y2);
|
||||
m_clip_box.normalize();
|
||||
m_clipping = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(coord_type x1, coord_type y1)
|
||||
{
|
||||
m_x1 = x1;
|
||||
m_y1 = y1;
|
||||
if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
AGG_INLINE void line_clip_y(Rasterizer& ras,
|
||||
coord_type x1, coord_type y1,
|
||||
coord_type x2, coord_type y2,
|
||||
unsigned f1, unsigned f2) const
|
||||
{
|
||||
f1 &= 10;
|
||||
f2 &= 10;
|
||||
if((f1 | f2) == 0)
|
||||
{
|
||||
// Fully visible
|
||||
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(f1 == f2)
|
||||
{
|
||||
// Invisible by Y
|
||||
return;
|
||||
}
|
||||
|
||||
coord_type tx1 = x1;
|
||||
coord_type ty1 = y1;
|
||||
coord_type tx2 = x2;
|
||||
coord_type ty2 = y2;
|
||||
|
||||
if(f1 & 8) // y1 < clip.y1
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
|
||||
ty1 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if(f1 & 2) // y1 > clip.y2
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
|
||||
ty1 = m_clip_box.y2;
|
||||
}
|
||||
|
||||
if(f2 & 8) // y2 < clip.y1
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
|
||||
ty2 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if(f2 & 2) // y2 > clip.y2
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
|
||||
ty2 = m_clip_box.y2;
|
||||
}
|
||||
ras.line(Conv::xi(tx1), Conv::yi(ty1),
|
||||
Conv::xi(tx2), Conv::yi(ty2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
if(m_clipping)
|
||||
{
|
||||
unsigned f2 = clipping_flags(x2, y2, m_clip_box);
|
||||
|
||||
if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
|
||||
{
|
||||
// Invisible by Y
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
m_f1 = f2;
|
||||
return;
|
||||
}
|
||||
|
||||
coord_type x1 = m_x1;
|
||||
coord_type y1 = m_y1;
|
||||
unsigned f1 = m_f1;
|
||||
coord_type y3, y4;
|
||||
unsigned f3, f4;
|
||||
|
||||
switch(((f1 & 5) << 1) | (f2 & 5))
|
||||
{
|
||||
case 0: // Visible by X
|
||||
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
|
||||
break;
|
||||
|
||||
case 1: // x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 2: // x1 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 3: // x1 > clip.x2 && x2 > clip.x2
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2);
|
||||
break;
|
||||
|
||||
case 4: // x2 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 6: // x1 > clip.x2 && x2 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
f4 = clipping_flags_y(y4, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4);
|
||||
line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2);
|
||||
break;
|
||||
|
||||
case 8: // x1 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 9: // x1 < clip.x1 && x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
f4 = clipping_flags_y(y4, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4);
|
||||
line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2);
|
||||
break;
|
||||
|
||||
case 12: // x1 < clip.x1 && x2 < clip.x1
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
|
||||
break;
|
||||
}
|
||||
m_f1 = f2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
|
||||
Conv::xi(x2), Conv::yi(y2));
|
||||
}
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
rect_type m_clip_box;
|
||||
coord_type m_x1;
|
||||
coord_type m_y1;
|
||||
unsigned m_f1;
|
||||
bool m_clipping;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------rasterizer_sl_no_clip
|
||||
class rasterizer_sl_no_clip
|
||||
{
|
||||
public:
|
||||
typedef ras_conv_int conv_type;
|
||||
typedef int coord_type;
|
||||
|
||||
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
|
||||
|
||||
void reset_clipping() {}
|
||||
void clip_box(coord_type, coord_type, coord_type, coord_type) {}
|
||||
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
|
||||
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
ras.line(m_x1, m_y1, x2, y2);
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_x1, m_y1;
|
||||
};
|
||||
|
||||
|
||||
// -----rasterizer_sl_clip_int
|
||||
// -----rasterizer_sl_clip_int_sat
|
||||
// -----rasterizer_sl_clip_int_3x
|
||||
// -----rasterizer_sl_clip_dbl
|
||||
// -----rasterizer_sl_clip_dbl_3x
|
||||
//------------------------------------------------------------------------
|
||||
typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
731
src/agg/agg_renderer_base.h
Normal file
731
src/agg/agg_renderer_base.h
Normal file
|
|
@ -0,0 +1,731 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class renderer_base
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_BASE_INCLUDED
|
||||
#define AGG_RENDERER_BASE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------renderer_base
|
||||
template<class PixelFormat> class renderer_base
|
||||
{
|
||||
public:
|
||||
typedef PixelFormat pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {}
|
||||
explicit renderer_base(pixfmt_type& ren) :
|
||||
m_ren(&ren),
|
||||
m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
|
||||
{}
|
||||
void attach(pixfmt_type& ren)
|
||||
{
|
||||
m_ren = &ren;
|
||||
m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const pixfmt_type& ren() const { return *m_ren; }
|
||||
pixfmt_type& ren() { return *m_ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_ren->width(); }
|
||||
unsigned height() const { return m_ren->height(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool clip_box(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rect_i cb(x1, y1, x2, y2);
|
||||
cb.normalize();
|
||||
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
|
||||
{
|
||||
m_clip_box = cb;
|
||||
return true;
|
||||
}
|
||||
m_clip_box.x1 = 1;
|
||||
m_clip_box.y1 = 1;
|
||||
m_clip_box.x2 = 0;
|
||||
m_clip_box.y2 = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping(bool visibility)
|
||||
{
|
||||
if(visibility)
|
||||
{
|
||||
m_clip_box.x1 = 0;
|
||||
m_clip_box.y1 = 0;
|
||||
m_clip_box.x2 = width() - 1;
|
||||
m_clip_box.y2 = height() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clip_box.x1 = 1;
|
||||
m_clip_box.y1 = 1;
|
||||
m_clip_box.x2 = 0;
|
||||
m_clip_box.y2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clip_box_naked(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
m_clip_box.x1 = x1;
|
||||
m_clip_box.y1 = y1;
|
||||
m_clip_box.x2 = x2;
|
||||
m_clip_box.y2 = y2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool inbox(int x, int y) const
|
||||
{
|
||||
return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
|
||||
x <= m_clip_box.x2 && y <= m_clip_box.y2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& clip_box() const { return m_clip_box; }
|
||||
int xmin() const { return m_clip_box.x1; }
|
||||
int ymin() const { return m_clip_box.y1; }
|
||||
int xmax() const { return m_clip_box.x2; }
|
||||
int ymax() const { return m_clip_box.y2; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& bounding_clip_box() const { return m_clip_box; }
|
||||
int bounding_xmin() const { return m_clip_box.x1; }
|
||||
int bounding_ymin() const { return m_clip_box.y1; }
|
||||
int bounding_xmax() const { return m_clip_box.x2; }
|
||||
int bounding_ymax() const { return m_clip_box.y2; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(const color_type& c)
|
||||
{
|
||||
unsigned y;
|
||||
if(width())
|
||||
{
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
m_ren->copy_hline(0, y, width(), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void fill(const color_type& c)
|
||||
{
|
||||
unsigned y;
|
||||
if(width())
|
||||
{
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
m_ren->blend_hline(0, y, width(), c, cover_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
if(inbox(x, y))
|
||||
{
|
||||
m_ren->copy_pixel(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
if(inbox(x, y))
|
||||
{
|
||||
m_ren->blend_pixel(x, y, c, cover);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y) const
|
||||
{
|
||||
return inbox(x, y) ?
|
||||
m_ren->pixel(x, y) :
|
||||
color_type::no_color();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_hline(int x1, int y, int x2, const color_type& c)
|
||||
{
|
||||
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
if(x1 > xmax()) return;
|
||||
if(x2 < xmin()) return;
|
||||
|
||||
if(x1 < xmin()) x1 = xmin();
|
||||
if(x2 > xmax()) x2 = xmax();
|
||||
|
||||
m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y1, int y2, const color_type& c)
|
||||
{
|
||||
if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
if(y1 > ymax()) return;
|
||||
if(y2 < ymin()) return;
|
||||
|
||||
if(y1 < ymin()) y1 = ymin();
|
||||
if(y2 > ymax()) y2 = ymax();
|
||||
|
||||
m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x1, int y, int x2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
if(x1 > xmax()) return;
|
||||
if(x2 < xmin()) return;
|
||||
|
||||
if(x1 < xmin()) x1 = xmin();
|
||||
if(x2 > xmax()) x2 = xmax();
|
||||
|
||||
m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y1, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
if(y1 > ymax()) return;
|
||||
if(y2 < ymin()) return;
|
||||
|
||||
if(y1 < ymin()) y1 = ymin();
|
||||
if(y2 > ymax()) y2 = ymax();
|
||||
|
||||
m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
|
||||
{
|
||||
rect_i rc(x1, y1, x2, y2);
|
||||
rc.normalize();
|
||||
if(rc.clip(clip_box()))
|
||||
{
|
||||
int y;
|
||||
for(y = rc.y1; y <= rc.y2; y++)
|
||||
{
|
||||
m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_bar(int x1, int y1, int x2, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
rect_i rc(x1, y1, x2, y2);
|
||||
rc.normalize();
|
||||
if(rc.clip(clip_box()))
|
||||
{
|
||||
int y;
|
||||
for(y = rc.y1; y <= rc.y2; y++)
|
||||
{
|
||||
m_ren->blend_hline(rc.x1,
|
||||
y,
|
||||
unsigned(rc.x2 - rc.x1 + 1),
|
||||
c,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y, int len,
|
||||
const color_type& c,
|
||||
const cover_type* covers)
|
||||
{
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
|
||||
if(x < xmin())
|
||||
{
|
||||
len -= xmin() - x;
|
||||
if(len <= 0) return;
|
||||
covers += xmin() - x;
|
||||
x = xmin();
|
||||
}
|
||||
if(x + len > xmax())
|
||||
{
|
||||
len = xmax() - x + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_solid_hspan(x, y, len, c, covers);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y, int len,
|
||||
const color_type& c,
|
||||
const cover_type* covers)
|
||||
{
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
|
||||
if(y < ymin())
|
||||
{
|
||||
len -= ymin() - y;
|
||||
if(len <= 0) return;
|
||||
covers += ymin() - y;
|
||||
y = ymin();
|
||||
}
|
||||
if(y + len > ymax())
|
||||
{
|
||||
len = ymax() - y + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_solid_vspan(x, y, len, c, covers);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y, int len, const color_type* colors)
|
||||
{
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
|
||||
if(x < xmin())
|
||||
{
|
||||
int d = xmin() - x;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
colors += d;
|
||||
x = xmin();
|
||||
}
|
||||
if(x + len > xmax())
|
||||
{
|
||||
len = xmax() - x + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->copy_color_hspan(x, y, len, colors);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_vspan(int x, int y, int len, const color_type* colors)
|
||||
{
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
|
||||
if(y < ymin())
|
||||
{
|
||||
int d = ymin() - y;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
colors += d;
|
||||
y = ymin();
|
||||
}
|
||||
if(y + len > ymax())
|
||||
{
|
||||
len = ymax() - y + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->copy_color_vspan(x, y, len, colors);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x, int y, int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
|
||||
if(x < xmin())
|
||||
{
|
||||
int d = xmin() - x;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
if(covers) covers += d;
|
||||
colors += d;
|
||||
x = xmin();
|
||||
}
|
||||
if(x + len > xmax())
|
||||
{
|
||||
len = xmax() - x + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x, int y, int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
|
||||
if(y < ymin())
|
||||
{
|
||||
int d = ymin() - y;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
if(covers) covers += d;
|
||||
colors += d;
|
||||
y = ymin();
|
||||
}
|
||||
if(y + len > ymax())
|
||||
{
|
||||
len = ymax() - y + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const
|
||||
{
|
||||
rect_i rc(0,0,0,0);
|
||||
rect_i cb = clip_box();
|
||||
++cb.x2;
|
||||
++cb.y2;
|
||||
|
||||
if(src.x1 < 0)
|
||||
{
|
||||
dst.x1 -= src.x1;
|
||||
src.x1 = 0;
|
||||
}
|
||||
if(src.y1 < 0)
|
||||
{
|
||||
dst.y1 -= src.y1;
|
||||
src.y1 = 0;
|
||||
}
|
||||
|
||||
if(src.x2 > wsrc) src.x2 = wsrc;
|
||||
if(src.y2 > hsrc) src.y2 = hsrc;
|
||||
|
||||
if(dst.x1 < cb.x1)
|
||||
{
|
||||
src.x1 += cb.x1 - dst.x1;
|
||||
dst.x1 = cb.x1;
|
||||
}
|
||||
if(dst.y1 < cb.y1)
|
||||
{
|
||||
src.y1 += cb.y1 - dst.y1;
|
||||
dst.y1 = cb.y1;
|
||||
}
|
||||
|
||||
if(dst.x2 > cb.x2) dst.x2 = cb.x2;
|
||||
if(dst.y2 > cb.y2) dst.y2 = cb.y2;
|
||||
|
||||
rc.x2 = dst.x2 - dst.x1;
|
||||
rc.y2 = dst.y2 - dst.y1;
|
||||
|
||||
if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
|
||||
if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
m_ren->copy_from(src,
|
||||
rdst.x1, rdst.y1,
|
||||
rsrc.x1, rsrc.y1,
|
||||
rc.x2);
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from(const SrcPixelFormatRenderer& src,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
|
||||
if(rw.ptr)
|
||||
{
|
||||
int x1src = rsrc.x1;
|
||||
int x1dst = rdst.x1;
|
||||
int len = rc.x2;
|
||||
if(rw.x1 > x1src)
|
||||
{
|
||||
x1dst += rw.x1 - x1src;
|
||||
len -= rw.x1 - x1src;
|
||||
x1src = rw.x1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
if(x1src + len-1 > rw.x2)
|
||||
{
|
||||
len -= x1src + len - rw.x2 - 1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
m_ren->blend_from(src,
|
||||
x1dst, rdst.y1,
|
||||
x1src, rsrc.y1,
|
||||
len,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_color(const SrcPixelFormatRenderer& src,
|
||||
const color_type& color,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
|
||||
if(rw.ptr)
|
||||
{
|
||||
int x1src = rsrc.x1;
|
||||
int x1dst = rdst.x1;
|
||||
int len = rc.x2;
|
||||
if(rw.x1 > x1src)
|
||||
{
|
||||
x1dst += rw.x1 - x1src;
|
||||
len -= rw.x1 - x1src;
|
||||
x1src = rw.x1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
if(x1src + len-1 > rw.x2)
|
||||
{
|
||||
len -= x1src + len - rw.x2 - 1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
m_ren->blend_from_color(src,
|
||||
color,
|
||||
x1dst, rdst.y1,
|
||||
x1src, rsrc.y1,
|
||||
len,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_lut(const SrcPixelFormatRenderer& src,
|
||||
const color_type* color_lut,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
|
||||
if(rw.ptr)
|
||||
{
|
||||
int x1src = rsrc.x1;
|
||||
int x1dst = rdst.x1;
|
||||
int len = rc.x2;
|
||||
if(rw.x1 > x1src)
|
||||
{
|
||||
x1dst += rw.x1 - x1src;
|
||||
len -= rw.x1 - x1src;
|
||||
x1src = rw.x1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
if(x1src + len-1 > rw.x2)
|
||||
{
|
||||
len -= x1src + len - rw.x2 - 1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
m_ren->blend_from_lut(src,
|
||||
color_lut,
|
||||
x1dst, rdst.y1,
|
||||
x1src, rsrc.y1,
|
||||
len,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
pixfmt_type* m_ren;
|
||||
rect_i m_clip_box;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
854
src/agg/agg_renderer_scanline.h
Normal file
854
src/agg/agg_renderer_scanline.h
Normal file
|
|
@ -0,0 +1,854 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_SCANLINE_INCLUDED
|
||||
#define AGG_RENDERER_SCANLINE_INCLUDED
|
||||
|
||||
#include <limits>
|
||||
#include <cstdlib>
|
||||
#include "agg_basics.h"
|
||||
#include "agg_renderer_base.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//================================================render_scanline_aa_solid
|
||||
template<class Scanline, class BaseRenderer, class ColorT>
|
||||
void render_scanline_aa_solid(const Scanline& sl,
|
||||
BaseRenderer& ren,
|
||||
const ColorT& color)
|
||||
{
|
||||
int y = sl.y();
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename Scanline::const_iterator span = sl.begin();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int x = span->x;
|
||||
if(span->len > 0)
|
||||
{
|
||||
ren.blend_solid_hspan(x, y, (unsigned)span->len,
|
||||
color,
|
||||
span->covers);
|
||||
}
|
||||
else
|
||||
{
|
||||
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
|
||||
color,
|
||||
*(span->covers));
|
||||
}
|
||||
if(--num_spans == 0) break;
|
||||
++span;
|
||||
}
|
||||
}
|
||||
|
||||
//===============================================render_scanlines_aa_solid
|
||||
template<class Rasterizer, class Scanline,
|
||||
class BaseRenderer, class ColorT>
|
||||
void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
|
||||
BaseRenderer& ren, const ColorT& color)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
// Explicitly convert "color" to the BaseRenderer color type.
|
||||
// For example, it can be called with color type "rgba", while
|
||||
// "rgba8" is needed. Otherwise it will be implicitly
|
||||
// converted in the loop many times.
|
||||
//----------------------
|
||||
typename BaseRenderer::color_type ren_color = color;
|
||||
|
||||
sl.reset(ras.min_x(), ras.max_x());
|
||||
while(ras.sweep_scanline(sl))
|
||||
{
|
||||
//render_scanline_aa_solid(sl, ren, ren_color);
|
||||
|
||||
// This code is equivalent to the above call (copy/paste).
|
||||
// It's just a "manual" optimization for old compilers,
|
||||
// like Microsoft Visual C++ v6.0
|
||||
//-------------------------------
|
||||
int y = sl.y();
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename Scanline::const_iterator span = sl.begin();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int x = span->x;
|
||||
if(span->len > 0)
|
||||
{
|
||||
ren.blend_solid_hspan(x, y, (unsigned)span->len,
|
||||
ren_color,
|
||||
span->covers);
|
||||
}
|
||||
else
|
||||
{
|
||||
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
|
||||
ren_color,
|
||||
*(span->covers));
|
||||
}
|
||||
if(--num_spans == 0) break;
|
||||
++span;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================renderer_scanline_aa_solid
|
||||
template<class BaseRenderer> class renderer_scanline_aa_solid
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef typename base_ren_type::color_type color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_scanline_aa_solid() : m_ren(0) {}
|
||||
explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
|
||||
void attach(base_ren_type& ren)
|
||||
{
|
||||
m_ren = &ren;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> void render(const Scanline& sl)
|
||||
{
|
||||
render_scanline_aa_solid(sl, *m_ren, m_color);
|
||||
}
|
||||
|
||||
private:
|
||||
base_ren_type* m_ren;
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//======================================================render_scanline_aa
|
||||
template<class Scanline, class BaseRenderer,
|
||||
class SpanAllocator, class SpanGenerator>
|
||||
void render_scanline_aa(const Scanline& sl, BaseRenderer& ren,
|
||||
SpanAllocator& alloc, SpanGenerator& span_gen)
|
||||
{
|
||||
int y = sl.y();
|
||||
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename Scanline::const_iterator span = sl.begin();
|
||||
for(;;)
|
||||
{
|
||||
int x = span->x;
|
||||
int len = span->len;
|
||||
const typename Scanline::cover_type* covers = span->covers;
|
||||
|
||||
if(len < 0) len = -len;
|
||||
typename BaseRenderer::color_type* colors = alloc.allocate(len);
|
||||
span_gen.generate(colors, x, y, len);
|
||||
ren.blend_color_hspan(x, y, len, colors,
|
||||
(span->len < 0) ? 0 : covers, *covers);
|
||||
|
||||
if(--num_spans == 0) break;
|
||||
++span;
|
||||
}
|
||||
}
|
||||
|
||||
//=====================================================render_scanlines_aa
|
||||
template<class Rasterizer, class Scanline, class BaseRenderer,
|
||||
class SpanAllocator, class SpanGenerator>
|
||||
void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
|
||||
SpanAllocator& alloc, SpanGenerator& span_gen)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
sl.reset(ras.min_x(), ras.max_x());
|
||||
span_gen.prepare();
|
||||
while(ras.sweep_scanline(sl))
|
||||
{
|
||||
render_scanline_aa(sl, ren, alloc, span_gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================renderer_scanline_aa
|
||||
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
|
||||
class renderer_scanline_aa
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef SpanAllocator alloc_type;
|
||||
typedef SpanGenerator span_gen_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
|
||||
renderer_scanline_aa(base_ren_type& ren,
|
||||
alloc_type& alloc,
|
||||
span_gen_type& span_gen) :
|
||||
m_ren(&ren),
|
||||
m_alloc(&alloc),
|
||||
m_span_gen(&span_gen)
|
||||
{}
|
||||
void attach(base_ren_type& ren,
|
||||
alloc_type& alloc,
|
||||
span_gen_type& span_gen)
|
||||
{
|
||||
m_ren = &ren;
|
||||
m_alloc = &alloc;
|
||||
m_span_gen = &span_gen;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() { m_span_gen->prepare(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> void render(const Scanline& sl)
|
||||
{
|
||||
render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
|
||||
}
|
||||
|
||||
private:
|
||||
base_ren_type* m_ren;
|
||||
alloc_type* m_alloc;
|
||||
span_gen_type* m_span_gen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===============================================render_scanline_bin_solid
|
||||
template<class Scanline, class BaseRenderer, class ColorT>
|
||||
void render_scanline_bin_solid(const Scanline& sl,
|
||||
BaseRenderer& ren,
|
||||
const ColorT& color)
|
||||
{
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename Scanline::const_iterator span = sl.begin();
|
||||
for(;;)
|
||||
{
|
||||
ren.blend_hline(span->x,
|
||||
sl.y(),
|
||||
span->x - 1 + ((span->len < 0) ?
|
||||
-span->len :
|
||||
span->len),
|
||||
color,
|
||||
cover_full);
|
||||
if(--num_spans == 0) break;
|
||||
++span;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================render_scanlines_bin_solid
|
||||
template<class Rasterizer, class Scanline,
|
||||
class BaseRenderer, class ColorT>
|
||||
void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
|
||||
BaseRenderer& ren, const ColorT& color)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
// Explicitly convert "color" to the BaseRenderer color type.
|
||||
// For example, it can be called with color type "rgba", while
|
||||
// "rgba8" is needed. Otherwise it will be implicitly
|
||||
// converted in the loop many times.
|
||||
//----------------------
|
||||
typename BaseRenderer::color_type ren_color(color);
|
||||
|
||||
sl.reset(ras.min_x(), ras.max_x());
|
||||
while(ras.sweep_scanline(sl))
|
||||
{
|
||||
//render_scanline_bin_solid(sl, ren, ren_color);
|
||||
|
||||
// This code is equivalent to the above call (copy/paste).
|
||||
// It's just a "manual" optimization for old compilers,
|
||||
// like Microsoft Visual C++ v6.0
|
||||
//-------------------------------
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename Scanline::const_iterator span = sl.begin();
|
||||
for(;;)
|
||||
{
|
||||
ren.blend_hline(span->x,
|
||||
sl.y(),
|
||||
span->x - 1 + ((span->len < 0) ?
|
||||
-span->len :
|
||||
span->len),
|
||||
ren_color,
|
||||
cover_full);
|
||||
if(--num_spans == 0) break;
|
||||
++span;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================renderer_scanline_bin_solid
|
||||
template<class BaseRenderer> class renderer_scanline_bin_solid
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef typename base_ren_type::color_type color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_scanline_bin_solid() : m_ren(0) {}
|
||||
explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {}
|
||||
void attach(base_ren_type& ren)
|
||||
{
|
||||
m_ren = &ren;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> void render(const Scanline& sl)
|
||||
{
|
||||
render_scanline_bin_solid(sl, *m_ren, m_color);
|
||||
}
|
||||
|
||||
private:
|
||||
base_ren_type* m_ren;
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//======================================================render_scanline_bin
|
||||
template<class Scanline, class BaseRenderer,
|
||||
class SpanAllocator, class SpanGenerator>
|
||||
void render_scanline_bin(const Scanline& sl, BaseRenderer& ren,
|
||||
SpanAllocator& alloc, SpanGenerator& span_gen)
|
||||
{
|
||||
int y = sl.y();
|
||||
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename Scanline::const_iterator span = sl.begin();
|
||||
for(;;)
|
||||
{
|
||||
int x = span->x;
|
||||
int len = span->len;
|
||||
if(len < 0) len = -len;
|
||||
typename BaseRenderer::color_type* colors = alloc.allocate(len);
|
||||
span_gen.generate(colors, x, y, len);
|
||||
ren.blend_color_hspan(x, y, len, colors, 0, cover_full);
|
||||
if(--num_spans == 0) break;
|
||||
++span;
|
||||
}
|
||||
}
|
||||
|
||||
//=====================================================render_scanlines_bin
|
||||
template<class Rasterizer, class Scanline, class BaseRenderer,
|
||||
class SpanAllocator, class SpanGenerator>
|
||||
void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
|
||||
SpanAllocator& alloc, SpanGenerator& span_gen)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
sl.reset(ras.min_x(), ras.max_x());
|
||||
span_gen.prepare();
|
||||
while(ras.sweep_scanline(sl))
|
||||
{
|
||||
render_scanline_bin(sl, ren, alloc, span_gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================renderer_scanline_bin
|
||||
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
|
||||
class renderer_scanline_bin
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef SpanAllocator alloc_type;
|
||||
typedef SpanGenerator span_gen_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {}
|
||||
renderer_scanline_bin(base_ren_type& ren,
|
||||
alloc_type& alloc,
|
||||
span_gen_type& span_gen) :
|
||||
m_ren(&ren),
|
||||
m_alloc(&alloc),
|
||||
m_span_gen(&span_gen)
|
||||
{}
|
||||
void attach(base_ren_type& ren,
|
||||
alloc_type& alloc,
|
||||
span_gen_type& span_gen)
|
||||
{
|
||||
m_ren = &ren;
|
||||
m_alloc = &alloc;
|
||||
m_span_gen = &span_gen;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() { m_span_gen->prepare(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> void render(const Scanline& sl)
|
||||
{
|
||||
render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
|
||||
}
|
||||
|
||||
private:
|
||||
base_ren_type* m_ren;
|
||||
alloc_type* m_alloc;
|
||||
span_gen_type* m_span_gen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//========================================================render_scanlines
|
||||
template<class Rasterizer, class Scanline, class Renderer>
|
||||
void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
sl.reset(ras.min_x(), ras.max_x());
|
||||
ren.prepare();
|
||||
while(ras.sweep_scanline(sl))
|
||||
{
|
||||
ren.render(sl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================render_all_paths
|
||||
template<class Rasterizer, class Scanline, class Renderer,
|
||||
class VertexSource, class ColorStorage, class PathId>
|
||||
void render_all_paths(Rasterizer& ras,
|
||||
Scanline& sl,
|
||||
Renderer& r,
|
||||
VertexSource& vs,
|
||||
const ColorStorage& as,
|
||||
const PathId& path_id,
|
||||
unsigned num_paths)
|
||||
{
|
||||
for(unsigned i = 0; i < num_paths; i++)
|
||||
{
|
||||
ras.reset();
|
||||
ras.add_path(vs, path_id[i]);
|
||||
r.color(as[i]);
|
||||
render_scanlines(ras, sl, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================render_scanlines_compound
|
||||
template<class Rasterizer,
|
||||
class ScanlineAA,
|
||||
class ScanlineBin,
|
||||
class BaseRenderer,
|
||||
class SpanAllocator,
|
||||
class StyleHandler>
|
||||
void render_scanlines_compound(Rasterizer& ras,
|
||||
ScanlineAA& sl_aa,
|
||||
ScanlineBin& sl_bin,
|
||||
BaseRenderer& ren,
|
||||
SpanAllocator& alloc,
|
||||
StyleHandler& sh)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
int min_x = ras.min_x();
|
||||
int len = ras.max_x() - min_x + 2;
|
||||
sl_aa.reset(min_x, ras.max_x());
|
||||
sl_bin.reset(min_x, ras.max_x());
|
||||
|
||||
typedef typename BaseRenderer::color_type color_type;
|
||||
color_type* color_span = alloc.allocate(len * 2);
|
||||
color_type* mix_buffer = color_span + len;
|
||||
unsigned num_spans;
|
||||
|
||||
unsigned num_styles;
|
||||
unsigned style;
|
||||
bool solid;
|
||||
while((num_styles = ras.sweep_styles()) > 0)
|
||||
{
|
||||
typename ScanlineAA::const_iterator span_aa;
|
||||
if(num_styles == 1)
|
||||
{
|
||||
// Optimization for a single style. Happens often
|
||||
//-------------------------
|
||||
if(ras.sweep_scanline(sl_aa, 0))
|
||||
{
|
||||
style = ras.style(0);
|
||||
if(sh.is_solid(style))
|
||||
{
|
||||
// Just solid fill
|
||||
//-----------------------
|
||||
render_scanline_aa_solid(sl_aa, ren, sh.color(style));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arbitrary span generator
|
||||
//-----------------------
|
||||
span_aa = sl_aa.begin();
|
||||
num_spans = sl_aa.num_spans();
|
||||
for(;;)
|
||||
{
|
||||
len = span_aa->len;
|
||||
sh.generate_span(color_span,
|
||||
span_aa->x,
|
||||
sl_aa.y(),
|
||||
len,
|
||||
style);
|
||||
|
||||
ren.blend_color_hspan(span_aa->x,
|
||||
sl_aa.y(),
|
||||
span_aa->len,
|
||||
color_span,
|
||||
span_aa->covers);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ras.sweep_scanline(sl_bin, -1))
|
||||
{
|
||||
// Clear the spans of the mix_buffer
|
||||
//--------------------
|
||||
typename ScanlineBin::const_iterator span_bin = sl_bin.begin();
|
||||
num_spans = sl_bin.num_spans();
|
||||
for(;;)
|
||||
{
|
||||
memset(mix_buffer + span_bin->x - min_x,
|
||||
0,
|
||||
span_bin->len * sizeof(color_type));
|
||||
|
||||
if(--num_spans == 0) break;
|
||||
++span_bin;
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
for(i = 0; i < num_styles; i++)
|
||||
{
|
||||
style = ras.style(i);
|
||||
solid = sh.is_solid(style);
|
||||
|
||||
if(ras.sweep_scanline(sl_aa, i))
|
||||
{
|
||||
color_type* colors;
|
||||
color_type* cspan;
|
||||
typename ScanlineAA::cover_type* covers;
|
||||
span_aa = sl_aa.begin();
|
||||
num_spans = sl_aa.num_spans();
|
||||
if(solid)
|
||||
{
|
||||
// Just solid fill
|
||||
//-----------------------
|
||||
for(;;)
|
||||
{
|
||||
color_type c = sh.color(style);
|
||||
len = span_aa->len;
|
||||
colors = mix_buffer + span_aa->x - min_x;
|
||||
covers = span_aa->covers;
|
||||
do
|
||||
{
|
||||
if(*covers == cover_full)
|
||||
{
|
||||
*colors = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors->add(c, *covers);
|
||||
}
|
||||
++colors;
|
||||
++covers;
|
||||
}
|
||||
while(--len);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arbitrary span generator
|
||||
//-----------------------
|
||||
for(;;)
|
||||
{
|
||||
len = span_aa->len;
|
||||
colors = mix_buffer + span_aa->x - min_x;
|
||||
cspan = color_span;
|
||||
sh.generate_span(cspan,
|
||||
span_aa->x,
|
||||
sl_aa.y(),
|
||||
len,
|
||||
style);
|
||||
covers = span_aa->covers;
|
||||
do
|
||||
{
|
||||
if(*covers == cover_full)
|
||||
{
|
||||
*colors = *cspan;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors->add(*cspan, *covers);
|
||||
}
|
||||
++cspan;
|
||||
++colors;
|
||||
++covers;
|
||||
}
|
||||
while(--len);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit the blended result as a color hspan
|
||||
//-------------------------
|
||||
span_bin = sl_bin.begin();
|
||||
num_spans = sl_bin.num_spans();
|
||||
for(;;)
|
||||
{
|
||||
ren.blend_color_hspan(span_bin->x,
|
||||
sl_bin.y(),
|
||||
span_bin->len,
|
||||
mix_buffer + span_bin->x - min_x,
|
||||
0,
|
||||
cover_full);
|
||||
if(--num_spans == 0) break;
|
||||
++span_bin;
|
||||
}
|
||||
} // if(ras.sweep_scanline(sl_bin, -1))
|
||||
} // if(num_styles == 1) ... else
|
||||
} // while((num_styles = ras.sweep_styles()) > 0)
|
||||
} // if(ras.rewind_scanlines())
|
||||
}
|
||||
|
||||
//=======================================render_scanlines_compound_layered
|
||||
template<class Rasterizer,
|
||||
class ScanlineAA,
|
||||
class BaseRenderer,
|
||||
class SpanAllocator,
|
||||
class StyleHandler>
|
||||
void render_scanlines_compound_layered(Rasterizer& ras,
|
||||
ScanlineAA& sl_aa,
|
||||
BaseRenderer& ren,
|
||||
SpanAllocator& alloc,
|
||||
StyleHandler& sh)
|
||||
{
|
||||
if(ras.rewind_scanlines())
|
||||
{
|
||||
int min_x = ras.min_x();
|
||||
int len = ras.max_x() - min_x + 2;
|
||||
sl_aa.reset(min_x, ras.max_x());
|
||||
|
||||
typedef typename BaseRenderer::color_type color_type;
|
||||
color_type* color_span = alloc.allocate(len * 2);
|
||||
color_type* mix_buffer = color_span + len;
|
||||
cover_type* cover_buffer = ras.allocate_cover_buffer(len);
|
||||
unsigned num_spans;
|
||||
|
||||
unsigned num_styles;
|
||||
unsigned style;
|
||||
bool solid;
|
||||
while((num_styles = ras.sweep_styles()) > 0)
|
||||
{
|
||||
typename ScanlineAA::const_iterator span_aa;
|
||||
if(num_styles == 1)
|
||||
{
|
||||
// Optimization for a single style. Happens often
|
||||
//-------------------------
|
||||
if(ras.sweep_scanline(sl_aa, 0))
|
||||
{
|
||||
style = ras.style(0);
|
||||
if(sh.is_solid(style))
|
||||
{
|
||||
// Just solid fill
|
||||
//-----------------------
|
||||
render_scanline_aa_solid(sl_aa, ren, sh.color(style));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arbitrary span generator
|
||||
//-----------------------
|
||||
span_aa = sl_aa.begin();
|
||||
num_spans = sl_aa.num_spans();
|
||||
for(;;)
|
||||
{
|
||||
len = span_aa->len;
|
||||
sh.generate_span(color_span,
|
||||
span_aa->x,
|
||||
sl_aa.y(),
|
||||
len,
|
||||
style);
|
||||
|
||||
ren.blend_color_hspan(span_aa->x,
|
||||
sl_aa.y(),
|
||||
span_aa->len,
|
||||
color_span,
|
||||
span_aa->covers);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sl_start = ras.scanline_start();
|
||||
unsigned sl_len = ras.scanline_length();
|
||||
|
||||
if(sl_len)
|
||||
{
|
||||
memset(mix_buffer + sl_start - min_x,
|
||||
0,
|
||||
sl_len * sizeof(color_type));
|
||||
|
||||
memset(cover_buffer + sl_start - min_x,
|
||||
0,
|
||||
sl_len * sizeof(cover_type));
|
||||
|
||||
int sl_y = std::numeric_limits<int>::max();
|
||||
unsigned i;
|
||||
for(i = 0; i < num_styles; i++)
|
||||
{
|
||||
style = ras.style(i);
|
||||
solid = sh.is_solid(style);
|
||||
|
||||
if(ras.sweep_scanline(sl_aa, i))
|
||||
{
|
||||
unsigned cover;
|
||||
color_type* colors;
|
||||
color_type* cspan;
|
||||
cover_type* src_covers;
|
||||
cover_type* dst_covers;
|
||||
span_aa = sl_aa.begin();
|
||||
num_spans = sl_aa.num_spans();
|
||||
sl_y = sl_aa.y();
|
||||
if(solid)
|
||||
{
|
||||
// Just solid fill
|
||||
//-----------------------
|
||||
for(;;)
|
||||
{
|
||||
color_type c = sh.color(style);
|
||||
len = span_aa->len;
|
||||
colors = mix_buffer + span_aa->x - min_x;
|
||||
src_covers = span_aa->covers;
|
||||
dst_covers = cover_buffer + span_aa->x - min_x;
|
||||
do
|
||||
{
|
||||
cover = *src_covers;
|
||||
if(*dst_covers + cover > cover_full)
|
||||
{
|
||||
cover = cover_full - *dst_covers;
|
||||
}
|
||||
if(cover)
|
||||
{
|
||||
colors->add(c, cover);
|
||||
*dst_covers += cover;
|
||||
}
|
||||
++colors;
|
||||
++src_covers;
|
||||
++dst_covers;
|
||||
}
|
||||
while(--len);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arbitrary span generator
|
||||
//-----------------------
|
||||
for(;;)
|
||||
{
|
||||
len = span_aa->len;
|
||||
colors = mix_buffer + span_aa->x - min_x;
|
||||
cspan = color_span;
|
||||
sh.generate_span(cspan,
|
||||
span_aa->x,
|
||||
sl_aa.y(),
|
||||
len,
|
||||
style);
|
||||
src_covers = span_aa->covers;
|
||||
dst_covers = cover_buffer + span_aa->x - min_x;
|
||||
do
|
||||
{
|
||||
cover = *src_covers;
|
||||
if(*dst_covers + cover > cover_full)
|
||||
{
|
||||
cover = cover_full - *dst_covers;
|
||||
}
|
||||
if(cover)
|
||||
{
|
||||
colors->add(*cspan, cover);
|
||||
*dst_covers += cover;
|
||||
}
|
||||
++cspan;
|
||||
++colors;
|
||||
++src_covers;
|
||||
++dst_covers;
|
||||
}
|
||||
while(--len);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ren.blend_color_hspan(sl_start,
|
||||
sl_y,
|
||||
sl_len,
|
||||
mix_buffer + sl_start - min_x,
|
||||
0,
|
||||
cover_full);
|
||||
} //if(sl_len)
|
||||
} //if(num_styles == 1) ... else
|
||||
} //while((num_styles = ras.sweep_styles()) > 0)
|
||||
} //if(ras.rewind_scanlines())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
300
src/agg/agg_rendering_buffer.h
Normal file
300
src/agg/agg_rendering_buffer.h
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class rendering_buffer
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERING_BUFFER_INCLUDED
|
||||
#define AGG_RENDERING_BUFFER_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===========================================================row_accessor
|
||||
template<class T> class row_accessor
|
||||
{
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
row_accessor() :
|
||||
m_buf(0),
|
||||
m_start(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
row_accessor(T* buf, unsigned width, unsigned height, int stride) :
|
||||
m_buf(0),
|
||||
m_start(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
m_buf = m_start = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if(stride < 0)
|
||||
{
|
||||
m_start = m_buf - int(height - 1) * stride;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* buf() { return m_buf; }
|
||||
AGG_INLINE const T* buf() const { return m_buf; }
|
||||
AGG_INLINE unsigned width() const { return m_width; }
|
||||
AGG_INLINE unsigned height() const { return m_height; }
|
||||
AGG_INLINE int stride() const { return m_stride; }
|
||||
AGG_INLINE unsigned stride_abs() const
|
||||
{
|
||||
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* row_ptr(int, int y, unsigned)
|
||||
{
|
||||
return m_start + y * m_stride;
|
||||
}
|
||||
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
|
||||
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
|
||||
AGG_INLINE row_data row (int y) const
|
||||
{
|
||||
return row_data(0, m_width-1, row_ptr(y));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src)
|
||||
{
|
||||
unsigned h = height();
|
||||
if(src.height() < h) h = src.height();
|
||||
|
||||
unsigned l = stride_abs();
|
||||
if(src.stride_abs() < l) l = src.stride_abs();
|
||||
|
||||
l *= sizeof(T);
|
||||
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(T value)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
unsigned stride = stride_abs();
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
T* p = row_ptr(0, y, w);
|
||||
unsigned x;
|
||||
for(x = 0; x < stride; x++)
|
||||
{
|
||||
*p++ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
T* m_buf; // Pointer to renrdering buffer
|
||||
T* m_start; // Pointer to first pixel depending on stride
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
int m_stride; // Number of bytes per row. Can be < 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================row_ptr_cache
|
||||
template<class T> class row_ptr_cache
|
||||
{
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
row_ptr_cache() :
|
||||
m_buf(0),
|
||||
m_rows(),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
|
||||
m_buf(0),
|
||||
m_rows(),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
m_buf = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if(height > m_rows.size())
|
||||
{
|
||||
m_rows.resize(height);
|
||||
}
|
||||
|
||||
T* row_ptr = m_buf;
|
||||
|
||||
if(stride < 0)
|
||||
{
|
||||
row_ptr = m_buf - int(height - 1) * stride;
|
||||
}
|
||||
|
||||
T** rows = &m_rows[0];
|
||||
|
||||
while(height--)
|
||||
{
|
||||
*rows++ = row_ptr;
|
||||
row_ptr += stride;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* buf() { return m_buf; }
|
||||
AGG_INLINE const T* buf() const { return m_buf; }
|
||||
AGG_INLINE unsigned width() const { return m_width; }
|
||||
AGG_INLINE unsigned height() const { return m_height; }
|
||||
AGG_INLINE int stride() const { return m_stride; }
|
||||
AGG_INLINE unsigned stride_abs() const
|
||||
{
|
||||
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* row_ptr(int, int y, unsigned)
|
||||
{
|
||||
return m_rows[y];
|
||||
}
|
||||
AGG_INLINE T* row_ptr(int y) { return m_rows[y]; }
|
||||
AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; }
|
||||
AGG_INLINE row_data row (int y) const
|
||||
{
|
||||
return row_data(0, m_width-1, m_rows[y]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
T const* const* rows() const { return &m_rows[0]; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src)
|
||||
{
|
||||
unsigned h = height();
|
||||
if(src.height() < h) h = src.height();
|
||||
|
||||
unsigned l = stride_abs();
|
||||
if(src.stride_abs() < l) l = src.stride_abs();
|
||||
|
||||
l *= sizeof(T);
|
||||
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(T value)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
unsigned stride = stride_abs();
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
T* p = row_ptr(0, y, w);
|
||||
unsigned x;
|
||||
for(x = 0; x < stride; x++)
|
||||
{
|
||||
*p++ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
T* m_buf; // Pointer to renrdering buffer
|
||||
pod_array<T*> m_rows; // Pointers to each row of the buffer
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
int m_stride; // Number of bytes per row. Can be < 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//========================================================rendering_buffer
|
||||
//
|
||||
// The definition of the main type for accessing the rows in the frame
|
||||
// buffer. It provides functionality to navigate to the rows in a
|
||||
// rectangular matrix, from top to bottom or from bottom to top depending
|
||||
// on stride.
|
||||
//
|
||||
// row_accessor is cheap to create/destroy, but performs one multiplication
|
||||
// when calling row_ptr().
|
||||
//
|
||||
// row_ptr_cache creates an array of pointers to rows, so, the access
|
||||
// via row_ptr() may be faster. But it requires memory allocation
|
||||
// when creating. For example, on typical Intel Pentium hardware
|
||||
// row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
|
||||
//
|
||||
// It's used only in short hand typedefs like pixfmt_rgba32 and can be
|
||||
// redefined in agg_config.h
|
||||
// In real applications you can use both, depending on your needs
|
||||
//------------------------------------------------------------------------
|
||||
#ifdef AGG_RENDERING_BUFFER
|
||||
typedef AGG_RENDERING_BUFFER rendering_buffer;
|
||||
#else
|
||||
// typedef row_ptr_cache<int8u> rendering_buffer;
|
||||
typedef row_accessor<int8u> rendering_buffer;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
329
src/agg/agg_scanline_p.h
Normal file
329
src/agg/agg_scanline_p.h
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Class scanline_p - a general purpose scanline container with packed spans.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SCANLINE_P_INCLUDED
|
||||
#define AGG_SCANLINE_P_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=============================================================scanline_p8
|
||||
//
|
||||
// This is a general purpose scaline container which supports the interface
|
||||
// used in the rasterizer::render(). See description of scanline_u8
|
||||
// for details.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_p8
|
||||
{
|
||||
public:
|
||||
typedef scanline_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
|
||||
scanline_p8() :
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers(),
|
||||
m_cover_ptr(0),
|
||||
m_spans(),
|
||||
m_cur_span(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_spans.size())
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = 1;
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len += (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)len;
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if(x == m_last_x+1 &&
|
||||
m_cur_span->len < 0 &&
|
||||
cover == *m_cur_span->covers)
|
||||
{
|
||||
m_cur_span->len -= (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr++;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)(-int(len));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
|
||||
private:
|
||||
scanline_p8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================scanline32_p8
|
||||
class scanline32_p8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int32 coord_type;
|
||||
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_, const cover_type* covers_) :
|
||||
x(x_), len(len_), covers(covers_) {}
|
||||
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans) :
|
||||
m_spans(spans),
|
||||
m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator ++ () { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_p8() :
|
||||
m_max_len(0),
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers(),
|
||||
m_cover_ptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_covers.size())
|
||||
{
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if(x == m_last_x+1 &&
|
||||
m_spans.size() &&
|
||||
m_spans.last().len < 0 &&
|
||||
cover == *m_spans.last().covers)
|
||||
{
|
||||
m_spans.last().len -= coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline32_p8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
unsigned m_max_len;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
518
src/agg/agg_trans_affine.h
Normal file
518
src/agg/agg_trans_affine.h
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Affine transformation classes.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_TRANS_AFFINE_INCLUDED
|
||||
#define AGG_TRANS_AFFINE_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
const double affine_epsilon = 1e-14;
|
||||
|
||||
//============================================================trans_affine
|
||||
//
|
||||
// See Implementation agg_trans_affine.cpp
|
||||
//
|
||||
// Affine transformation are linear transformations in Cartesian coordinates
|
||||
// (strictly speaking not only in Cartesian, but for the beginning we will
|
||||
// think so). They are rotation, scaling, translation and skewing.
|
||||
// After any affine transformation a line segment remains a line segment
|
||||
// and it will never become a curve.
|
||||
//
|
||||
// There will be no math about matrix calculations, since it has been
|
||||
// described many times. Ask yourself a very simple question:
|
||||
// "why do we need to understand and use some matrix stuff instead of just
|
||||
// rotating, scaling and so on". The answers are:
|
||||
//
|
||||
// 1. Any combination of transformations can be done by only 4 multiplications
|
||||
// and 4 additions in floating point.
|
||||
// 2. One matrix transformation is equivalent to the number of consecutive
|
||||
// discrete transformations, i.e. the matrix "accumulates" all transformations
|
||||
// in the order of their settings. Suppose we have 4 transformations:
|
||||
// * rotate by 30 degrees,
|
||||
// * scale X to 2.0,
|
||||
// * scale Y to 1.5,
|
||||
// * move to (100, 100).
|
||||
// The result will depend on the order of these transformations,
|
||||
// and the advantage of matrix is that the sequence of discret calls:
|
||||
// rotate(30), scaleX(2.0), scaleY(1.5), move(100,100)
|
||||
// will have exactly the same result as the following matrix transformations:
|
||||
//
|
||||
// affine_matrix m;
|
||||
// m *= rotate_matrix(30);
|
||||
// m *= scaleX_matrix(2.0);
|
||||
// m *= scaleY_matrix(1.5);
|
||||
// m *= move_matrix(100,100);
|
||||
//
|
||||
// m.transform_my_point_at_last(x, y);
|
||||
//
|
||||
// What is the good of it? In real life we will set-up the matrix only once
|
||||
// and then transform many points, let alone the convenience to set any
|
||||
// combination of transformations.
|
||||
//
|
||||
// So, how to use it? Very easy - literally as it's shown above. Not quite,
|
||||
// let us write a correct example:
|
||||
//
|
||||
// agg::trans_affine m;
|
||||
// m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0);
|
||||
// m *= agg::trans_affine_scaling(2.0, 1.5);
|
||||
// m *= agg::trans_affine_translation(100.0, 100.0);
|
||||
// m.transform(&x, &y);
|
||||
//
|
||||
// The affine matrix is all you need to perform any linear transformation,
|
||||
// but all transformations have origin point (0,0). It means that we need to
|
||||
// use 2 translations if we want to rotate someting around (100,100):
|
||||
//
|
||||
// m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0)
|
||||
// m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate
|
||||
// m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100)
|
||||
//----------------------------------------------------------------------
|
||||
struct trans_affine
|
||||
{
|
||||
double sx, shy, shx, sy, tx, ty;
|
||||
|
||||
//------------------------------------------ Construction
|
||||
// Identity matrix
|
||||
trans_affine() :
|
||||
sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0)
|
||||
{}
|
||||
|
||||
// Custom matrix. Usually used in derived classes
|
||||
trans_affine(double v0, double v1, double v2,
|
||||
double v3, double v4, double v5) :
|
||||
sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5)
|
||||
{}
|
||||
|
||||
// Custom matrix from m[6]
|
||||
explicit trans_affine(const double* m) :
|
||||
sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5])
|
||||
{}
|
||||
|
||||
// Rectangle to a parallelogram.
|
||||
trans_affine(double x1, double y1, double x2, double y2,
|
||||
const double* parl)
|
||||
{
|
||||
rect_to_parl(x1, y1, x2, y2, parl);
|
||||
}
|
||||
|
||||
// Parallelogram to a rectangle.
|
||||
trans_affine(const double* parl,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
parl_to_rect(parl, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
// Arbitrary parallelogram transformation.
|
||||
trans_affine(const double* src, const double* dst)
|
||||
{
|
||||
parl_to_parl(src, dst);
|
||||
}
|
||||
|
||||
//---------------------------------- Parellelogram transformations
|
||||
// transform a parallelogram to another one. Src and dst are
|
||||
// pointers to arrays of three points (double[6], x1,y1,...) that
|
||||
// identify three corners of the parallelograms assuming implicit
|
||||
// fourth point. The arguments are arrays of double[6] mapped
|
||||
// to x1,y1, x2,y2, x3,y3 where the coordinates are:
|
||||
// *-----------------*
|
||||
// / (x3,y3)/
|
||||
// / /
|
||||
// /(x1,y1) (x2,y2)/
|
||||
// *-----------------*
|
||||
const trans_affine& parl_to_parl(const double* src,
|
||||
const double* dst);
|
||||
|
||||
const trans_affine& rect_to_parl(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* parl);
|
||||
|
||||
const trans_affine& parl_to_rect(const double* parl,
|
||||
double x1, double y1,
|
||||
double x2, double y2);
|
||||
|
||||
|
||||
//------------------------------------------ Operations
|
||||
// Reset - load an identity matrix
|
||||
const trans_affine& reset();
|
||||
|
||||
// Direct transformations operations
|
||||
const trans_affine& translate(double x, double y);
|
||||
const trans_affine& rotate(double a);
|
||||
const trans_affine& scale(double s);
|
||||
const trans_affine& scale(double x, double y);
|
||||
|
||||
// Multiply matrix to another one
|
||||
const trans_affine& multiply(const trans_affine& m);
|
||||
|
||||
// Multiply "m" to "this" and assign the result to "this"
|
||||
const trans_affine& premultiply(const trans_affine& m);
|
||||
|
||||
// Multiply matrix to inverse of another one
|
||||
const trans_affine& multiply_inv(const trans_affine& m);
|
||||
|
||||
// Multiply inverse of "m" to "this" and assign the result to "this"
|
||||
const trans_affine& premultiply_inv(const trans_affine& m);
|
||||
|
||||
// Invert matrix. Do not try to invert degenerate matrices,
|
||||
// there's no check for validity. If you set scale to 0 and
|
||||
// then try to invert matrix, expect unpredictable result.
|
||||
const trans_affine& invert();
|
||||
|
||||
// Mirroring around X
|
||||
const trans_affine& flip_x();
|
||||
|
||||
// Mirroring around Y
|
||||
const trans_affine& flip_y();
|
||||
|
||||
//------------------------------------------- Load/Store
|
||||
// Store matrix to an array [6] of double
|
||||
void store_to(double* m) const
|
||||
{
|
||||
*m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty;
|
||||
}
|
||||
|
||||
// Load matrix from an array [6] of double
|
||||
const trans_affine& load_from(const double* m)
|
||||
{
|
||||
sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------- Operators
|
||||
|
||||
// Multiply the matrix by another one
|
||||
const trans_affine& operator *= (const trans_affine& m)
|
||||
{
|
||||
return multiply(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
const trans_affine& operator /= (const trans_affine& m)
|
||||
{
|
||||
return multiply_inv(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by another one and return
|
||||
// the result in a separete matrix.
|
||||
trans_affine operator * (const trans_affine& m) const
|
||||
{
|
||||
return trans_affine(*this).multiply(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
// and return the result in a separete matrix.
|
||||
trans_affine operator / (const trans_affine& m) const
|
||||
{
|
||||
return trans_affine(*this).multiply_inv(m);
|
||||
}
|
||||
|
||||
// Calculate and return the inverse matrix
|
||||
trans_affine operator ~ () const
|
||||
{
|
||||
trans_affine ret = *this;
|
||||
return ret.invert();
|
||||
}
|
||||
|
||||
// Equal operator with default epsilon
|
||||
bool operator == (const trans_affine& m) const
|
||||
{
|
||||
return is_equal(m, affine_epsilon);
|
||||
}
|
||||
|
||||
// Not Equal operator with default epsilon
|
||||
bool operator != (const trans_affine& m) const
|
||||
{
|
||||
return !is_equal(m, affine_epsilon);
|
||||
}
|
||||
|
||||
//-------------------------------------------- Transformations
|
||||
// Direct transformation of x and y
|
||||
void transform(double* x, double* y) const;
|
||||
|
||||
// Direct transformation of x and y, 2x2 matrix only, no translation
|
||||
void transform_2x2(double* x, double* y) const;
|
||||
|
||||
// Inverse transformation of x and y. It works slower than the
|
||||
// direct transformation. For massive operations it's better to
|
||||
// invert() the matrix and then use direct transformations.
|
||||
void inverse_transform(double* x, double* y) const;
|
||||
|
||||
//-------------------------------------------- Auxiliary
|
||||
// Calculate the determinant of matrix
|
||||
double determinant() const
|
||||
{
|
||||
return sx * sy - shy * shx;
|
||||
}
|
||||
|
||||
// Calculate the reciprocal of the determinant
|
||||
double determinant_reciprocal() const
|
||||
{
|
||||
return 1.0 / (sx * sy - shy * shx);
|
||||
}
|
||||
|
||||
// Get the average scale (by X and Y).
|
||||
// Basically used to calculate the approximation_scale when
|
||||
// decomposinting curves into line segments.
|
||||
double scale() const;
|
||||
|
||||
// Check to see if the matrix is not degenerate
|
||||
bool is_valid(double epsilon = affine_epsilon) const;
|
||||
|
||||
// Check to see if it's an identity matrix
|
||||
bool is_identity(double epsilon = affine_epsilon) const;
|
||||
|
||||
// Check to see if two matrices are equal
|
||||
bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const;
|
||||
|
||||
// Determine the major parameters. Use with caution considering
|
||||
// possible degenerate cases.
|
||||
double rotation() const;
|
||||
void translation(double* dx, double* dy) const;
|
||||
void scaling(double* x, double* y) const;
|
||||
void scaling_abs(double* x, double* y) const;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::transform(double* x, double* y) const
|
||||
{
|
||||
double tmp = *x;
|
||||
*x = tmp * sx + *y * shx + tx;
|
||||
*y = tmp * shy + *y * sy + ty;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::transform_2x2(double* x, double* y) const
|
||||
{
|
||||
double tmp = *x;
|
||||
*x = tmp * sx + *y * shx;
|
||||
*y = tmp * shy + *y * sy;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::inverse_transform(double* x, double* y) const
|
||||
{
|
||||
double d = determinant_reciprocal();
|
||||
double a = (*x - tx) * d;
|
||||
double b = (*y - ty) * d;
|
||||
*x = a * sy - b * shx;
|
||||
*y = b * sx - a * shy;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline double trans_affine::scale() const
|
||||
{
|
||||
double x = 0.707106781 * sx + 0.707106781 * shx;
|
||||
double y = 0.707106781 * shy + 0.707106781 * sy;
|
||||
return sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::translate(double x, double y)
|
||||
{
|
||||
tx += x;
|
||||
ty += y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::rotate(double a)
|
||||
{
|
||||
double ca = cos(a);
|
||||
double sa = sin(a);
|
||||
double t0 = sx * ca - shy * sa;
|
||||
double t2 = shx * ca - sy * sa;
|
||||
double t4 = tx * ca - ty * sa;
|
||||
shy = sx * sa + shy * ca;
|
||||
sy = shx * sa + sy * ca;
|
||||
ty = tx * sa + ty * ca;
|
||||
sx = t0;
|
||||
shx = t2;
|
||||
tx = t4;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::scale(double x, double y)
|
||||
{
|
||||
double mm0 = x; // Possible hint for the optimizer
|
||||
double mm3 = y;
|
||||
sx *= mm0;
|
||||
shx *= mm0;
|
||||
tx *= mm0;
|
||||
shy *= mm3;
|
||||
sy *= mm3;
|
||||
ty *= mm3;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::scale(double s)
|
||||
{
|
||||
double m = s; // Possible hint for the optimizer
|
||||
sx *= m;
|
||||
shx *= m;
|
||||
tx *= m;
|
||||
shy *= m;
|
||||
sy *= m;
|
||||
ty *= m;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::premultiply(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
return *this = t.multiply(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
t.invert();
|
||||
return multiply(t);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
t.invert();
|
||||
return *this = t.multiply(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::scaling_abs(double* x, double* y) const
|
||||
{
|
||||
// Used to calculate scaling coefficients in image resampling.
|
||||
// When there is considerable shear this method gives us much
|
||||
// better estimation than just sx, sy.
|
||||
*x = sqrt(sx * sx + shx * shx);
|
||||
*y = sqrt(shy * shy + sy * sy);
|
||||
}
|
||||
|
||||
//====================================================trans_affine_rotation
|
||||
// Rotation matrix. sin() and cos() are calculated twice for the same angle.
|
||||
// There's no harm because the performance of sin()/cos() is very good on all
|
||||
// modern processors. Besides, this operation is not going to be invoked too
|
||||
// often.
|
||||
class trans_affine_rotation : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_rotation(double a) :
|
||||
trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//====================================================trans_affine_scaling
|
||||
// Scaling matrix. x, y - scale coefficients by X and Y respectively
|
||||
class trans_affine_scaling : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_scaling(double x, double y) :
|
||||
trans_affine(x, 0.0, 0.0, y, 0.0, 0.0)
|
||||
{}
|
||||
|
||||
trans_affine_scaling(double s) :
|
||||
trans_affine(s, 0.0, 0.0, s, 0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//================================================trans_affine_translation
|
||||
// Translation matrix
|
||||
class trans_affine_translation : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_translation(double x, double y) :
|
||||
trans_affine(1.0, 0.0, 0.0, 1.0, x, y)
|
||||
{}
|
||||
};
|
||||
|
||||
//====================================================trans_affine_skewing
|
||||
// Sckewing (shear) matrix
|
||||
class trans_affine_skewing : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_skewing(double x, double y) :
|
||||
trans_affine(1.0, tan(y), tan(x), 1.0, 0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//===============================================trans_affine_line_segment
|
||||
// Rotate, Scale and Translate, associating 0...dist with line segment
|
||||
// x1,y1,x2,y2
|
||||
class trans_affine_line_segment : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_line_segment(double x1, double y1, double x2, double y2,
|
||||
double dist)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
if(dist > 0.0)
|
||||
{
|
||||
multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist));
|
||||
}
|
||||
multiply(trans_affine_rotation(atan2(dy, dx)));
|
||||
multiply(trans_affine_translation(x1, y1));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//============================================trans_affine_reflection_unit
|
||||
// Reflection matrix. Reflect coordinates across the line through
|
||||
// the origin containing the unit vector (ux, uy).
|
||||
// Contributed by John Horigan
|
||||
class trans_affine_reflection_unit : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_reflection_unit(double ux, double uy) :
|
||||
trans_affine(2.0 * ux * ux - 1.0,
|
||||
2.0 * ux * uy,
|
||||
2.0 * ux * uy,
|
||||
2.0 * uy * uy - 1.0,
|
||||
0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//=================================================trans_affine_reflection
|
||||
// Reflection matrix. Reflect coordinates across the line through
|
||||
// the origin at the angle a or containing the non-unit vector (x, y).
|
||||
// Contributed by John Horigan
|
||||
class trans_affine_reflection : public trans_affine_reflection_unit
|
||||
{
|
||||
public:
|
||||
trans_affine_reflection(double a) :
|
||||
trans_affine_reflection_unit(cos(a), sin(a))
|
||||
{}
|
||||
|
||||
|
||||
trans_affine_reflection(double x, double y) :
|
||||
trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y))
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
65
src/agg/copying
Normal file
65
src/agg/copying
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
The Anti-Grain Geometry Project
|
||||
A high quality rendering engine for C++
|
||||
http://antigrain.com
|
||||
|
||||
Anti-Grain Geometry has dual licensing model. The Modified BSD
|
||||
License was first added in version v2.4 just for convenience.
|
||||
It is a simple, permissive non-copyleft free software license,
|
||||
compatible with the GNU GPL. It's well proven and recognizable.
|
||||
See http://www.fsf.org/licensing/licenses/index_html#ModifiedBSD
|
||||
for details.
|
||||
|
||||
Note that the Modified BSD license DOES NOT restrict your rights
|
||||
if you choose the Anti-Grain Geometry Public License.
|
||||
|
||||
|
||||
|
||||
|
||||
Anti-Grain Geometry Public License
|
||||
====================================================
|
||||
|
||||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
|
||||
Permission to copy, use, modify, sell and distribute this software
|
||||
is granted provided this copyright notice appears in all copies.
|
||||
This software is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Modified BSD License
|
||||
====================================================
|
||||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
28
src/avrdude/AUTHORS
Normal file
28
src/avrdude/AUTHORS
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
AVRDUDE was written by:
|
||||
|
||||
Brian S. Dean <bsd@bdmicro.com>
|
||||
|
||||
Contributors:
|
||||
|
||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
Eric Weddington <ericw@evcohs.com>
|
||||
Jan-Hinnerk Reichert <hinni@despammed.com>
|
||||
Alex Shepherd <maillists@ajsystems.co.nz>
|
||||
Martin Thomas <mthomas@rhrk.uni-kl.de>
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
Michael Holzt <kju-avr@fqdn.org>
|
||||
Colin O'Flynn <coflynn@newae.com>
|
||||
Thomas Fischl <tfischl@gmx.de>
|
||||
David Hoerl <dhoerl@mac.com>
|
||||
Michal Ludvig <mludvig@logix.net.nz>
|
||||
Darell Tan <darell.tan@gmail.com>
|
||||
Wolfgang Moser
|
||||
Ville Voipio
|
||||
Hannes Weisbach
|
||||
Doug Springer
|
||||
Brett Hagman <bhagman@roguerobotics.com>
|
||||
Rene Liebscher <r.liebscher@gmx.de>
|
||||
Jim Paris <jim@jtan.com>
|
||||
|
||||
For minor contributions, please see the ChangeLog files.
|
||||
|
||||
13
src/avrdude/BUILD-FROM-SVN
Normal file
13
src/avrdude/BUILD-FROM-SVN
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
$Id$
|
||||
|
||||
How to build avrdude from SVN:
|
||||
|
||||
1. svn co svn://svn.savannah.nongnu.org/avrdude/trunk
|
||||
|
||||
2. cd trunk/avrdude
|
||||
|
||||
3. ./bootstrap
|
||||
|
||||
4. ./configure
|
||||
|
||||
5. make
|
||||
87
src/avrdude/CMakeLists.txt
Normal file
87
src/avrdude/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
|
||||
add_definitions(-D_BSD_SOURCE -D_DEFAULT_SOURCE) # To enable various useful macros and functions on Unices
|
||||
remove_definitions(-D_UNICODE -DUNICODE)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# Workaround for an old CMake, which does not understand CMAKE_C_STANDARD.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall")
|
||||
endif()
|
||||
|
||||
|
||||
set(AVRDUDE_SOURCES
|
||||
arduino.c
|
||||
avr.c
|
||||
# avrftdi.c
|
||||
# avrftdi_tpi.c
|
||||
avrpart.c
|
||||
avr910.c
|
||||
bitbang.c
|
||||
buspirate.c
|
||||
butterfly.c
|
||||
config.c
|
||||
config_gram.c
|
||||
# confwin.c
|
||||
crc16.c
|
||||
# dfu.c
|
||||
fileio.c
|
||||
# flip1.c
|
||||
# flip2.c
|
||||
# ft245r.c
|
||||
# jtagmkI.c
|
||||
# jtagmkII.c
|
||||
# jtag3.c
|
||||
lexer.c
|
||||
linuxgpio.c
|
||||
lists.c
|
||||
# par.c
|
||||
pgm.c
|
||||
pgm_type.c
|
||||
pickit2.c
|
||||
pindefs.c
|
||||
# ppi.c
|
||||
# ppiwin.c
|
||||
safemode.c
|
||||
ser_avrdoper.c
|
||||
serbb_posix.c
|
||||
serbb_win32.c
|
||||
ser_posix.c
|
||||
ser_win32.c
|
||||
stk500.c
|
||||
stk500generic.c
|
||||
stk500v2.c
|
||||
term.c
|
||||
update.c
|
||||
# usbasp.c
|
||||
# usb_hidapi.c
|
||||
# usb_libusb.c
|
||||
# usbtiny.c
|
||||
wiring.c
|
||||
|
||||
main.c
|
||||
avrdude-slic3r.hpp
|
||||
avrdude-slic3r.cpp
|
||||
)
|
||||
if (WIN32)
|
||||
set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES}
|
||||
windows/unistd.cpp
|
||||
windows/getopt.c
|
||||
)
|
||||
endif()
|
||||
add_library(avrdude STATIC ${AVRDUDE_SOURCES})
|
||||
|
||||
set(STANDALONE_SOURCES
|
||||
main-standalone.c
|
||||
)
|
||||
add_executable(avrdude-slic3r ${STANDALONE_SOURCES})
|
||||
target_link_libraries(avrdude-slic3r avrdude)
|
||||
set_target_properties(avrdude-slic3r PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
if (WIN32)
|
||||
target_compile_definitions(avrdude PRIVATE WIN32NATIVE=1)
|
||||
target_include_directories(avrdude SYSTEM PRIVATE windows) # So that sources find the getopt.h windows drop-in
|
||||
endif()
|
||||
339
src/avrdude/COPYING
Normal file
339
src/avrdude/COPYING
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
90
src/avrdude/ChangeLog
Normal file
90
src/avrdude/ChangeLog
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
2016-05-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Hannes Jochriem:
|
||||
* avrdude.conf.in (ehajo-isp): New programmer.
|
||||
|
||||
2016-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libftdi1): Rather than hardcoding the library
|
||||
providing the libusb-1.0 API, use the result from the previous
|
||||
probe. This helps detecting libftdi1 on FreeBSD where the
|
||||
libusb-1.0 API is provided by the system's libusb.
|
||||
|
||||
2016-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_hidapi.c (usbhid_open): Correctly calculate the
|
||||
offset for serial number matching
|
||||
|
||||
2016-03-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #47550: Linux GPIO broken
|
||||
* linuxgpio.c: Replace %ud by %u in snprintf calls.
|
||||
|
||||
2016-03-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_hidapi.c (usbhid_recv): Bump read timeout to 300 ms.
|
||||
|
||||
2016-02-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: add support for libhidapi as (optional) transport for
|
||||
CMSIS-DAP compliant debuggers (JTAGICE3 with firmware 3+,
|
||||
AtmelICE, EDBG, mEDBG)
|
||||
* usb_hidapi.c: (New file)
|
||||
* libavrdude.h: Mention usbhid_serdev
|
||||
* configure.ac: Bump version date
|
||||
|
||||
2016-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
(Obtained from patch #8717: pattch for mcprog and libhidapi support)
|
||||
* configure.ac: Probe for libhidapi
|
||||
* Makefile.am: Add @LIBHIDAPI@
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Bump copyright year.
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.3.
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.3.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8894: Spelling in 6.2 doc
|
||||
* doc/avrdude.texi: Various spelling fixes.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8895: Spelling in 6.2 code
|
||||
* avrftdi.c (avrftdi_open): Spell fix.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
* linuxgpio.c: Use %ud to print GPIO values.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8735: ATtiny28 support in avrdude.conf
|
||||
* avrdude.conf.in (ATtiny28): New device.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega48PB, ATmega88PB, ATmega168PB): New
|
||||
devices.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
* usb_libusb.c: Add endpoint IDs for Xplained Mini, correctly
|
||||
transfer trailing ZLP when needed
|
||||
* avrdude.conf.in (xplainedmini, xplainedmini_dw): New entries.
|
||||
* jtag3.c (jtag3_edbg_send, jtag3_edbg_recv_frame): Implement
|
||||
fragmentation needed for the 64-byte EP size of the Xplained Mini
|
||||
* avrdude.1: Document the change
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
|
||||
598
src/avrdude/ChangeLog-2001
Normal file
598
src/avrdude/ChangeLog-2001
Normal file
|
|
@ -0,0 +1,598 @@
|
|||
2001-12-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Update version.
|
||||
|
||||
* avrdude.conf.sample: Clarify a comment.
|
||||
|
||||
* avrdude.conf.sample: fix address bits
|
||||
|
||||
* avrdude.1: Bring up to date.
|
||||
|
||||
2001-12-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: Add the AVR3 progammer.
|
||||
|
||||
* avr.c, avrdude.conf.sample, config_gram.y, main.c, pindefs.h:
|
||||
Fix VCC assertion.
|
||||
|
||||
Make the BUFF pin a mask like VCC to allow multiple pins to be
|
||||
asserted at the same time (STK200 has two buffer enable lines).
|
||||
|
||||
Add the STK200 programmer.
|
||||
|
||||
Fix EEPROM address line selection for several parts.
|
||||
|
||||
2001-12-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: fix spelling error
|
||||
|
||||
2001-11-24 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile:
|
||||
Change "WARNING" to "NOTE" when overwriting the avrprog.conf file.
|
||||
|
||||
* avrdude.1: Add my e-mail address.
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Add comments about instruction formats. Correct an instruction
|
||||
specification (cut&paste error).
|
||||
|
||||
2001-11-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, config_gram.y, lexer.l, term.c:
|
||||
In interactive mode, reset the address and length if we start dumping
|
||||
a memory type different than the previous one.
|
||||
|
||||
* avr.c, avrdude.conf.sample, config_gram.y:
|
||||
Allow instruction data to be specified more flexibly, which can be
|
||||
used to make the instruction input more readable in the config file.
|
||||
|
||||
* main.c: Bump version number.
|
||||
|
||||
* Makefile, avr.c, avr.h, avrdude.conf.sample, config.c, config.h:
|
||||
* config_gram.y, fileio.c, fileio.h, lexer.l, main.c, term.c:
|
||||
This is a major re-write of the programming algorithms. The Atmel
|
||||
serial programming instructions are not very orthoganal, i.e., the
|
||||
"read fuse bits" instruction on an ATMega103 is an entirely different
|
||||
opcode and data format from the _same_ instruction for an ATMega163!
|
||||
Thus, it becomes impossible to have a single instruction encoding
|
||||
(varying the data) across the chip lines.
|
||||
|
||||
This set of changes allows and requires instruction encodings to be
|
||||
defined on a per-part basis within the configuration file. Hopefully
|
||||
I've defined the encoding scheme in a general enough way so it is
|
||||
useful in describing the instruction formats for yet-to-be invented
|
||||
Atmel chips. I've tried hard to make it match very closely with the
|
||||
specification in Atmel's data sheets for their parts. It's a little
|
||||
more verbose than what I initially hoped for, but I've tried to keep
|
||||
it as concise as I could, while still remaining reasonably flexible.
|
||||
|
||||
2001-11-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, main.c, ppi.c, term.c:
|
||||
Add support for ATMega163.
|
||||
|
||||
Add support for reading/writing ATMega163 lock and fuse bits.
|
||||
Unfortunately, in looking at the specs for other ATMega parts, they
|
||||
use entirely different instruction formats for these commands. Thus,
|
||||
these routines won't work for the ATMega103, for example.
|
||||
|
||||
Add support for sending raw command bytes via the interactive terminal
|
||||
interface. This allows one to execute any programming instruction on
|
||||
the target device, whether or not avrprog supports it explicitly or
|
||||
not. Thus, one can use this feature to program fuse / lock bits, or
|
||||
access any other feature of a current or future device that avrprog
|
||||
does not know how to do.
|
||||
|
||||
Add in comments, an experimental instruction format in the
|
||||
configuration file. If this works out, it would allow supporting new
|
||||
parts and non-orthoganal instructions across existing parts without
|
||||
making avrprog code changes.
|
||||
|
||||
2001-11-17 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: Add ATMEGA163 part.
|
||||
|
||||
2001-11-11 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: output formatting
|
||||
|
||||
2001-11-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* ppi.c: Get ppi.h from /usr/include, not /sys.
|
||||
|
||||
2001-10-31 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avrdude.conf.sample, main.c: Correct version string.
|
||||
Update read/write status more frequently.
|
||||
Prefix ATMega parts with an 'm'.
|
||||
|
||||
2001-10-16 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c: Change ording for memory display.
|
||||
|
||||
* config_gram.y: comment
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, config_gram.y, lexer.l, term.c:
|
||||
Fix (again, hopefully) page addressing for the ATMega parts.
|
||||
|
||||
Rename the poorly chosen name "bank" to "page" for page addressing.
|
||||
Atmel calls it "page" in their documentation.
|
||||
|
||||
* config_gram.y, main.c: Fix an (non)exit.
|
||||
Silence a couple of compiler warnings.
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, config_gram.y, main.c:
|
||||
Fix ATMega flash addressing. Add an ATMEGA16 part. Perform sanity
|
||||
checking on the memory parameters for parts that do bank addressing.
|
||||
|
||||
2001-10-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* config.c, config.h, lists.h: Add copyright.
|
||||
|
||||
* config_gram.y, lexer.l, lists.c: Add copyrights.
|
||||
|
||||
* Makefile: Attempt to install avrprog.conf.
|
||||
|
||||
* avrdude.conf.sample: Correct dt006 pinout.
|
||||
|
||||
* Makefile, lexer.l:
|
||||
Try and detect an old-style config file and print an appropriate error
|
||||
message and a suggestion for correcting it.
|
||||
|
||||
* Makefile, avr.c, avrdude.1, avrdude.conf.sample: Update the man page.
|
||||
|
||||
Miscellaneous minor cleanups.
|
||||
|
||||
2001-10-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, Makefile.inc, avr.c, avr.h, avrdude.conf.sample:
|
||||
* config.c, config.h, config_gram.y, lexer.l, lists.c, lists.h:
|
||||
* main.c, pindefs.h, term.c:
|
||||
Use lex/yacc for parsing the config file. Re-work the config file
|
||||
format using a more human-readable format.
|
||||
|
||||
Read part descriptions from the config file now instead of hard-coding
|
||||
them.
|
||||
|
||||
Update usage().
|
||||
|
||||
Cleanup unused code.
|
||||
|
||||
* Makefile, avr.c, avr.h, fileio.c, term.c:
|
||||
First cut at supporting the ATmega 103 which uses bank addressing and
|
||||
has a 128K flash.
|
||||
|
||||
Due to the bank addressing required, interactive update of the flash
|
||||
is not supported, though the eeprom can be updated interactively.
|
||||
Both memories can be programmed via non-interactive mode.
|
||||
|
||||
Intel Hex Record type '04' is now generated as required for outputing
|
||||
memory contents that go beyond 64K.
|
||||
|
||||
2001-10-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avr.h, fileio.c, fileio.h, main.c, ppi.c, ppi.h, term.c:
|
||||
* term.h:
|
||||
Style fixes.
|
||||
|
||||
* avr.c, avr.h, fileio.c, fileio.h, main.c, term.c:
|
||||
Commit changes in preparation for support the ATMega line.
|
||||
|
||||
2001-10-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile: Don't override CFLAGS.
|
||||
|
||||
* avrdude.1: Correct default pin assignment.
|
||||
|
||||
* avr.c, fileio.c, main.c, ppi.c, term.c:
|
||||
Remove debugging code - it served its purpose.
|
||||
|
||||
Update copyrights.
|
||||
|
||||
2001-09-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c:
|
||||
Be sure to read the exit specs after the pin configuration has been
|
||||
assigned, otherwise, we may apply the exit specs to the wrong pins.
|
||||
|
||||
* main.c: debugging
|
||||
|
||||
2001-09-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1, avrdude.conf.sample, main.c:
|
||||
Prefix pin config entries in the config file with a "c:". Later, I
|
||||
might make part descriptions read in this way and we can use a
|
||||
different letter for those (p). This will make the parsing easier to
|
||||
distinguish between the entry types.
|
||||
|
||||
* main.c: Initialize pin configuration description.
|
||||
|
||||
2001-09-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* AVRprog.pdf, Makefile, avr.c, avrdude.1, avrdude.conf.sample:
|
||||
* avrdude.pdf, fileio.c, fileio.h, main.c, pindefs.h, term.c:
|
||||
Make the pin definitions configurable based on entries in a config
|
||||
file. This makes supporting other programmers much easier.
|
||||
|
||||
Rename AVRprog.pdf to avrprog.pdf.
|
||||
|
||||
2001-04-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog-programmer.jpg: Remove this image file from the repository.
|
||||
|
||||
2001-04-26 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog-schematic.jpg:
|
||||
Remove this image, use AVRprog.pdf as the preferred schematic for the
|
||||
programmer.
|
||||
|
||||
2001-04-25 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* AVRprog.pdf, Makefile, avrdude.1:
|
||||
Add a schematic provided by Joerg Wunch and also update the manual
|
||||
page (also updated by Joerg) to reference the schematic.
|
||||
|
||||
2001-02-25 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, Makefile.inc: Automate dependency generation.
|
||||
|
||||
2001-02-08 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Turn off ready led when finished programming.
|
||||
|
||||
* main.c: update version
|
||||
|
||||
* avr.c, main.c: Correct a few comments.
|
||||
|
||||
* Makefile, avr.c, term.c: Makefile : update dependencies
|
||||
|
||||
avr.c : correct status led updates
|
||||
|
||||
term.c : update status leds on write, make the address and length
|
||||
arguments for dump optional.
|
||||
|
||||
2001-01-26 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Version 1.1
|
||||
|
||||
* main.c:
|
||||
Hmmm ... cvs co -D <timestamp> does not work. Change the revision
|
||||
timestamp to a full date/time value.
|
||||
|
||||
* avr.c, fileio.c, main.c, ppi.c, term.c:
|
||||
Add a -V option to display the version information about each
|
||||
component module. This is intended for support purposes, so that I
|
||||
can tell unambiguously what version a binary out in the field is.
|
||||
|
||||
Additionally, display a revision timestamp along with the version
|
||||
number. This also is intended for aiding in support and is the Unix
|
||||
time of the latest component module. Having this, should allow me to
|
||||
do a "cvs co -D timestamp avrprog" and get exactly the source of the
|
||||
version that is being reported.
|
||||
|
||||
* fileio.c:
|
||||
Return the maximum address (+1) written as opposed to the actual
|
||||
number of bytes written. The presence of an Intel Hex address
|
||||
record can cause these two number to be different; but the callers
|
||||
of this routine need the former.
|
||||
|
||||
* main.c:
|
||||
Fix a place where we were exiting without applying the exit-specs.
|
||||
|
||||
Wrap a long line.
|
||||
|
||||
* avr.c, fileio.c: avr.c: Update a comment.
|
||||
|
||||
fileio.c: Properly handle all the Intel Hex record types that I can
|
||||
find information about.
|
||||
|
||||
2001-01-25 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Usage, avr.h: Get rid of the Usage file.
|
||||
|
||||
2001-01-24 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avr.c, avr.h, main.c, pindefs.h, ppi.c:
|
||||
Move pin definitions to their own file.
|
||||
|
||||
First pass at providing feedback via the optionally connected leds. I
|
||||
don't actually have any of these attached to my programmer, so I can
|
||||
only guess as whether this is toggling them on and off correctly.
|
||||
|
||||
Also, enable and disable the optional 74367 buffer.
|
||||
|
||||
* avr.h, main.c, ppi.c, ppi.h, avr.c:
|
||||
Rearrange the pinout for the programmer to be a little more logical.
|
||||
Provide hooks to support a buffered programmer, pin 6 is now used to
|
||||
enable a buffer that can be used to isolate the target system from the
|
||||
parallel port pins. This is important when programming the target
|
||||
in-system.
|
||||
|
||||
Totally change the way the pin definitions are defined. Actually
|
||||
set/clear pins based on the way more intuitive pin number, instead of
|
||||
PPI data register, bit number combination. A table of pin data is
|
||||
used so that any hardware inversion done by the parallel port is
|
||||
accounted for, what you set is actually what appears at the pin.
|
||||
Retain the old method for handling Vcc, however, because the hold
|
||||
method is much easier to use when setting / retrieving multiple pins
|
||||
simultaneously.
|
||||
|
||||
2001-01-22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile: Don't gzip the man page.
|
||||
|
||||
* avrdude.1: .Nm macro fix. Submitted by Joerg.
|
||||
|
||||
* main.c: Cosmetic, don't output a preceding linefeed for usage().
|
||||
|
||||
* Makefile, avr.c, avr.h, fileio.c, term.c:
|
||||
Makefile : use gzip -f for man page installation so that we don't get
|
||||
prompted.
|
||||
|
||||
avr.c avr.h fileio.c term.c :
|
||||
|
||||
Change the avrpart data structure so that the typedef AVRMEM is
|
||||
used as an index into an array for the sizes of the memory types
|
||||
and also for pointers to buffers that represent the chip data for
|
||||
that memory type. This removes a lot of conditional code of the
|
||||
form:
|
||||
|
||||
switch (memtype) {
|
||||
case AVR_FLASH :
|
||||
...
|
||||
}
|
||||
|
||||
Also, re-code avr_read_byte() and avr_write_byte() to properly
|
||||
handle the flash memory type without having to tell them whether
|
||||
they should program the high byte or the low byte - figure that
|
||||
out from the address itself. For flash memory type, these
|
||||
routines now take the actual byte address instead of the word
|
||||
address. This _greatly_ simplifies many otherwise simple
|
||||
operations, such a reading or writing a range of memory, by not
|
||||
having to worry about whether the address starts on an odd byte
|
||||
or an even byte.
|
||||
|
||||
2001-01-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avr.h, fileio.c, fileio.h, main.c:
|
||||
Return error codes instead of exiting, thus making sure that we exit
|
||||
only via main() so that the exitspecs are properly applied.
|
||||
|
||||
When reading input data from a file, remember how many bytes were read
|
||||
and write and verify only that many bytes.
|
||||
|
||||
Don't complain when an input file size is smaller than the memory size
|
||||
we are programming. This is normal.
|
||||
|
||||
* fileio.c:
|
||||
Correct checksum calculation; failure to account for the value of the
|
||||
record type was causing non-zero record types to be calculated
|
||||
incorrectly.
|
||||
|
||||
* Makefile, main.c: Makefile : install the man page
|
||||
|
||||
main.c : drop the giant usage text now that we have a man page.
|
||||
|
||||
* avrdude.1:
|
||||
Add initial man page graciously contributed by Joerg Wunsch. Thanks
|
||||
Joerg!
|
||||
|
||||
2001-01-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* term.c:
|
||||
Accept abbreviations for eeprom and flash for the dump and write
|
||||
commands.
|
||||
|
||||
Fix small bug keeping 1 character command lines from being added to
|
||||
the history.
|
||||
|
||||
* term.c:
|
||||
Implement enough state in cmd_dump so that if it is called with no
|
||||
arguments, it successively dumps the next chunk of data of the same
|
||||
previously specified length.
|
||||
|
||||
* term.c, term.h, fileio.c, fileio.h, main.c, ppi.c, ppi.h:
|
||||
* Makefile, avr.c, avr.h, avrprog.c:
|
||||
The program was getting too large for a single file. Split it up into
|
||||
more modular pieces.
|
||||
|
||||
Also, accept command abbreviations as long as they are not ambiguous.
|
||||
|
||||
* avrprog.c:
|
||||
Add ability to specify the state of the power and reset pins on
|
||||
program exit. Default to leaving the pins in the state they were when
|
||||
we found them.
|
||||
|
||||
Contributed by: Joerg Wunsch
|
||||
|
||||
2001-01-18 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrprog.c:
|
||||
Switch to using readline() for getting terminal input. I can't seem
|
||||
to get the history capabilities working yet, but even so, it does
|
||||
better handling of the prompt and strips newlines for us, so it's
|
||||
still a win.
|
||||
|
||||
Add a few new commands for terminal mode: help, sig, part, erase.
|
||||
Display rudimentory help using the help command.
|
||||
|
||||
Add some function prototypes.
|
||||
|
||||
* Usage, avrprog.c:
|
||||
Change -c (interactive command mode) to the more intuitive -t
|
||||
(terminal mode).
|
||||
|
||||
Make binary format the default for output.
|
||||
|
||||
Update the parts table with corrections for old values and add some
|
||||
new values.
|
||||
|
||||
2001-01-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c:
|
||||
Automatically verify on-chip data with what we just programmed.
|
||||
|
||||
* avrprog.c, Makefile:
|
||||
Prepare the Makefile for integration into the FreeBSD ports tree.
|
||||
|
||||
Fix a few "may be used uninitialized" bugs found by -Wall.
|
||||
|
||||
2001-01-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Free a buffer.
|
||||
|
||||
* avrprog.c:
|
||||
Use a smarter programming algorithm - read the existing data byte
|
||||
first and only write the new one if it is different.
|
||||
|
||||
Add -n option which is a test mode in which the chip is not actually
|
||||
updated. This option does not affect writes in interactive mode.
|
||||
|
||||
* avrprog.c: Add the "dump" and "write" interactive commands.
|
||||
|
||||
* avrprog.c:
|
||||
Correctly produce and handle "end of record" for intel hex files.
|
||||
|
||||
2001-01-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c:
|
||||
Re-enable writing to the chip. I should probably should make this a
|
||||
command-line selectable option so that I don't keep forgetting and
|
||||
committing it with it disabled.
|
||||
|
||||
* avrprog.c:
|
||||
Add a newline before exiting due to command line errors. Perform a
|
||||
bit more option compatibility testing between -c, -i, and -o.
|
||||
|
||||
* avrprog.c: Add input file format auto-detection support.
|
||||
|
||||
* Usage, avrprog.c: Say what the defaults are.
|
||||
|
||||
* avrprog-programmer.jpg, Usage, avrprog-schematic.jpg: New files.
|
||||
|
||||
* avrprog.c: Correct usage text.
|
||||
|
||||
* avrprog.c:
|
||||
Parameterize a few additional items per chip. Print out all per-chip
|
||||
parameters on startup. Use the per-chip parameters in the code
|
||||
instead of hard-coded values for the 2313.
|
||||
|
||||
* avrprog.c: Fix filename assignment error.
|
||||
|
||||
Clean up debugging code a little, utilize fileio() instead of making
|
||||
direct calls to b2ihex().
|
||||
|
||||
* avrprog.c: A lot of general code cleanup.
|
||||
|
||||
Re-work command line options to be more intuitive.
|
||||
|
||||
Support Intel Hex input and output file formats. Provide hooks to
|
||||
support Motorola S-Record as well.
|
||||
|
||||
Add a few more part-specific parameters to the avrpart structure.
|
||||
|
||||
Only write the flash or eeprom if the data to be written is not 0xff.
|
||||
|
||||
2000-12-31 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Update a comment.
|
||||
|
||||
* avrprog.c:
|
||||
Provide the ability to tie additionally tie pins 6-9 of the parallel
|
||||
port to Vcc in order to supply more current.
|
||||
|
||||
Fix a typo on the size of the S1200's Flash.
|
||||
|
||||
Bring RESET low when programming is completed.
|
||||
|
||||
* avrprog.c:
|
||||
Correct pin connection comments. Elaborate a bit on Vcc connection.
|
||||
|
||||
* avrprog.c:
|
||||
Update after receiving some good feedback from Joerg Wunsch. We
|
||||
should now be able to program AT90S1200's.
|
||||
|
||||
2000-12-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Don't limit eeprom addresses.
|
||||
|
||||
2000-12-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrprog.c:
|
||||
Add support for the 8515. Make the addition for other devices easier.
|
||||
|
||||
2000-08-27 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c:
|
||||
Clear all bits except AVR_RESET when finished reading or programming
|
||||
the Atmel device.
|
||||
|
||||
2000-08-07 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: update announcement message
|
||||
|
||||
* avrprog.c: Update announcement message.
|
||||
|
||||
* avrprog.c: Return the correct return code from 'main()'.
|
||||
|
||||
* avrprog.c:
|
||||
Add ppi_pulse() function and fix ppi_toggle() to actully toggle
|
||||
instead of pulse.
|
||||
|
||||
Make all abnormal returns after the parallel port has been opened go
|
||||
through a single exit point at the bottom of 'main()'.
|
||||
|
||||
2000-08-06 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrprog.c: Makefile: add --pedantic compiler option
|
||||
|
||||
avrprog.c:
|
||||
|
||||
Add lots of comments, move getop() variable declarations to
|
||||
the top of the program.
|
||||
|
||||
Add a typedef name to the AVR memory type and use it for
|
||||
function declarations.
|
||||
|
||||
Add a usleep() delay in the sense loop to avoid becoming a cpu
|
||||
hog.
|
||||
|
||||
Print out a version string so that folks know what version of
|
||||
the software they are running.
|
||||
|
||||
Be sure and close the parallel device and the i/o file when
|
||||
terminating abnormally.
|
||||
|
||||
* avrprog.c: Print out version information when invoked.
|
||||
|
||||
* Makefile, avrprog.c: Makefile: Add an install target.
|
||||
|
||||
avrprog.c:
|
||||
|
||||
Add license.
|
||||
|
||||
Document the header a bit better.
|
||||
|
||||
Add capability to read out and display the device signature bytes.
|
||||
|
||||
Add capability to power the device from the parallel port.
|
||||
|
||||
Eliminate debug print facility.
|
||||
|
||||
Provide 'avr_cmd()' function.
|
||||
|
||||
When memory locations don't program, generate a newline so that the
|
||||
information is not overwritten and lost.
|
||||
|
||||
Don't print out the message about needing to specify a file if the
|
||||
user is not requesting an operation that requires the file.
|
||||
|
||||
2000-08-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Pring usage when no arguments are supplied.
|
||||
|
||||
* Makefile, avrprog.c: Initial check-in
|
||||
|
||||
* Makefile, avrprog.c: New file.
|
||||
|
||||
237
src/avrdude/ChangeLog-2002
Normal file
237
src/avrdude/ChangeLog-2002
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
2002-12-12 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: minor cleanup
|
||||
|
||||
2002-12-07 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1, main.c:
|
||||
If the stk500 is being used, default to using the first serial port.
|
||||
|
||||
2002-12-03 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1: Mention STK500 support.
|
||||
|
||||
2002-12-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* stk500.c: Remove unused code.
|
||||
|
||||
* CHANGELOG, stk500.c:
|
||||
Document changes since the previous version in the CHANGELOG.
|
||||
|
||||
Cleanup stk500.c a bit.
|
||||
|
||||
* stk500.c: Fix cut and paste braino.
|
||||
|
||||
* avr.c, avrdude.conf.sample, main.c, pgm.h, stk500.c:
|
||||
The STK500 can perform paged read/write operations even on standard
|
||||
"non-paged" parts. Take advantage of that and use the faster internal
|
||||
routines of the STK500 for those parts as well.
|
||||
|
||||
* avr.c, avr.h, avrpart.h, main.c, pgm.c, pgm.h, stk500.c:
|
||||
Optimize reading and writing for the STK500 programmer if the part
|
||||
supports paged reads and writes. This greatly decreases the
|
||||
program/verify time from about 4.5 minutes down to about 10 seconds in
|
||||
a 12K program size test case.
|
||||
|
||||
Print out the hardware and firmware version for the STK500 if verbose
|
||||
is enabled.
|
||||
|
||||
* avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l, pgm.h:
|
||||
* ppi.c, ppi.h, stk500.c, stk500.h, stk500_private.h:
|
||||
Add basic support for STK500.
|
||||
|
||||
2002-11-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample, config.c, config.h, config_gram.y, lexer.l:
|
||||
* main.c, pgm.c, pgm.h, ppi.c, ppi.h, term.c, term.h, Makefile:
|
||||
* avr.c, avr.h:
|
||||
Seperate programmer operations out into a driver-like interface so
|
||||
that programmers other than the direct parallel port connection can be
|
||||
supported.
|
||||
|
||||
2002-11-23 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, main.c, term.c:
|
||||
term.c - when in interactive terminal mode and dumping memory using
|
||||
the 'dump <memtype>' command without any address information,
|
||||
and the end of memory is reached, wrap back around to zero on
|
||||
the next invocation.
|
||||
|
||||
CHANGELOG - describe changes
|
||||
|
||||
main.c - update version number
|
||||
|
||||
* main.c:
|
||||
When getting ready to initiate communications with the AVR device,
|
||||
first pull /RESET low for a short period of time before enabling the
|
||||
buffer chip. This sequence allows the AVR to be reset before the
|
||||
buffer is enabled to avoid a short period of time where the AVR may be
|
||||
driving the programming lines at the same time the programmer tries
|
||||
to. Of course, if a buffer is being used, then the /RESET line from
|
||||
the programmer needs to be directly connected to the AVR /RESET line
|
||||
and not via the buffer chip.
|
||||
|
||||
2002-11-06 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Update changelog.
|
||||
|
||||
* avr.c, avr.h, main.c: Fix -Y option. Reported by Joerg Wunsch.
|
||||
|
||||
2002-11-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, main.c: Version update and CHANGELOG entry.
|
||||
|
||||
* avr.c:
|
||||
Be backward compatible with the 2-byte rewrite cycle counter which
|
||||
appeared in version 2.1.0, but was changed to a 4 byte counter in
|
||||
version 2.1.1. Reminded by Joerg Wunsch.
|
||||
|
||||
2002-10-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, avrdude.1, main.c:
|
||||
Add '-V' (no verify) flag requested by Joerg Wunsch. Update the man
|
||||
page.
|
||||
|
||||
2002-10-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, avrdude.1: Update man page and changelog.
|
||||
|
||||
* main.c: Update version number.
|
||||
|
||||
2002-10-12 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile: Remove --pedantic and -g from the compiler options.
|
||||
|
||||
2002-10-11 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, term.c:
|
||||
Use a four byte value instead of a two byte value for the programming
|
||||
cycle count stored at the end of EEPROM. It seems as though Atmel was
|
||||
greatly conservative in claiming a 1000 count reliability for the
|
||||
FLASH. I current have a part that has been reprogrammed 173330 times,
|
||||
and counting.
|
||||
|
||||
Fix a compiler warning.
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Fix ATMega128 instruction encoding for reading the low and high fuse
|
||||
bits. Thanks to Joerg Wunsch for tripping over this.
|
||||
|
||||
2002-08-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avrdude.1, main.c:
|
||||
Move erase-rewrite cycle increment to within the chip erase routine so
|
||||
that it is tracked no matter where the erase was initiated: command
|
||||
line mode or interactive mode, without code duplicaiton.
|
||||
|
||||
* CHANGELOG: Recent updates.
|
||||
|
||||
* avr.c: Eliminate unused variables.
|
||||
|
||||
* avr.c, avr.h, avrdude.1, fileio.c, main.c:
|
||||
Implement a way of tracking how many erase-rewrite cycles a part has
|
||||
undergone. This utilizes the last two bytes of EEPROM to maintain a
|
||||
counter that is incremented each time the part is erased.
|
||||
|
||||
2002-07-27 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, main.c:
|
||||
Fix a typo in a comment. Display the size of memory being written.
|
||||
Display the correct memory name in an error message (previously
|
||||
hardcoded).
|
||||
|
||||
2002-06-22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, avrdude.conf.sample:
|
||||
Add support for ATtiny15 - contributed by Asher Hoskins
|
||||
<asher@crumbly.freeserve.co.uk>
|
||||
|
||||
2002-04-23 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Say what changed.
|
||||
|
||||
2002-04-07 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrdude.conf.sample:
|
||||
Backup the config file to a timestamped name to keep from possibly
|
||||
overwriting user-modified configs.
|
||||
|
||||
Add read/write instructions for all memory types for ATMEGA103,
|
||||
ATMEGA128, ATMEGA16, and ATMEGA8.
|
||||
|
||||
2002-04-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Add support for ATMEGA128; untested; requested by Jeff Gardner
|
||||
<gardner@journey.com>.
|
||||
|
||||
2002-02-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: Minor ordering.
|
||||
|
||||
* CHANGELOG, main.c: Update version numbers.
|
||||
|
||||
2002-02-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Summarize latest updates.
|
||||
|
||||
* avrdude.conf.sample, config_gram.y:
|
||||
Make pwroff_after_write a yes/no field instead of a numeric.
|
||||
|
||||
* avrdude.conf.sample: Document the pwroff_after_write flag.
|
||||
|
||||
* avr.c: Enable the extra part verbosity when verbosity >= 3.
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, config_gram.y, lexer.l:
|
||||
* main.c, term.c:
|
||||
Fix error reporting by avr_write_byte().
|
||||
|
||||
Fix setting of status LEDs under various write-fail conditions.
|
||||
|
||||
Add a flag to indicate that a memory type requires the device to
|
||||
possibly be powered off and back on after a write to it. This is due
|
||||
to a hardware problem on some Atmel devices, see:
|
||||
|
||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf
|
||||
|
||||
Add greater verbosity to the part-display code when verbose>1 to
|
||||
display avrprog's encoding of the defined programming instructions.
|
||||
This is primarily for debugging purposes.
|
||||
|
||||
|
||||
Part updates:
|
||||
|
||||
* add the AT90S4414 part
|
||||
|
||||
* add fuse and lock bit access instructions for the AT90S1200,
|
||||
AT90S4434, and AT90S8515.
|
||||
|
||||
* add the pwroff_after_write flag to the fuse bits for the AT90S2333
|
||||
and AT90S4433 parts
|
||||
|
||||
2002-02-09 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Updates to the 2333 and 4433 parts, contributed by Joerg Wunsh.
|
||||
|
||||
2002-01-18 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Add changelog.
|
||||
|
||||
2002-01-12 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Add (c) to copyright.
|
||||
|
||||
* fileio.c, fileio.h, lexer.l, lists.c, lists.h, main.c:
|
||||
* pindefs.h, ppi.c, ppi.h, term.c, term.h, avr.c, avr.h:
|
||||
* config.c, config.h, config_gram.y:
|
||||
Update version number. Update copyright.
|
||||
|
||||
* avrdude.1: Update copyright and add description of "default".
|
||||
|
||||
Submitted by: Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr.c, term.c:
|
||||
Fix programming of write-only memories (such as lock bits on the
|
||||
2313).
|
||||
|
||||
1095
src/avrdude/ChangeLog-2003
Normal file
1095
src/avrdude/ChangeLog-2003
Normal file
File diff suppressed because it is too large
Load diff
1644
src/avrdude/ChangeLog-2004-2006
Normal file
1644
src/avrdude/ChangeLog-2004-2006
Normal file
File diff suppressed because it is too large
Load diff
364
src/avrdude/ChangeLog-2007
Normal file
364
src/avrdude/ChangeLog-2007
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
2007-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Partially revert the line buffered output change,
|
||||
and turn stderr into unbuffered output while producing the
|
||||
progress report.
|
||||
|
||||
2007-11-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add setup and teardown hooks to the programmer
|
||||
definition. If present, call the setup hook immediately after
|
||||
finding the respective programmer object, and schedule the
|
||||
teardown hook to be called upon exit. This allows the
|
||||
programmer implementation to dynamically allocate private
|
||||
programmer data.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* avr910.c: Convert static programmer data into dynamically
|
||||
allocated data.
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Remove the no_show_func_info() calls, as Brian
|
||||
promised some 4 years ago.
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add the -x option to pass extended parameters to
|
||||
the programmer backend.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* jtagmkII.c: Implement the extended parameter jtagchain=
|
||||
to support JTAG daisy-chains.
|
||||
* avrdude.1: Document all of the above.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.5.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <bikenomad@gmail.com>:
|
||||
patch #5007: Patch for line-buffering of stdout and stderr
|
||||
* main.c: call setvbuf() for stdout and stderr.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <graceindustries@gmail.com>:
|
||||
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf
|
||||
* avrdude.conf.in: Add entry for AT90CAN64 and AT90CAN32.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Wolfgang Moser:
|
||||
patch #6121: ISP support for the C2N232I device (serial port
|
||||
bitbanging)
|
||||
* avrdude.conf.in: Add entry for c2n232i.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <karl.yerkes@gmail.com>:
|
||||
patch #6141: accept binary format immediate values
|
||||
* fileio.c: Detect a 0b prefix, and call strtoul() differently
|
||||
in that case.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21076: -vvvv serial receive prints are empty in Win32 build
|
||||
* ser_win32.c (ser_recv): Drop the essentially unused variable
|
||||
"len", and use the variable "read" in order to track how many
|
||||
bytes have just been read in.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21145: atmega329p not recognized
|
||||
* avrdude.conf.in: Add definitions for the ATmega329P/3290P.
|
||||
Same as ATmega329/3290 except of the different signature.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21152: Unable to program atmega324p with avrdude 5.4 and AVRISP
|
||||
using default configuration file.
|
||||
* avrdude.conf.in: Uncomment the (bogus) stk500_devcode lines for
|
||||
the ATmega164P, ATmega324P, ATmega644, and ATmega644P definitions.
|
||||
This only affects users of STK500v1 firmware.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <ladyada@gmail.com>:
|
||||
Patch #6233: Add support for USBtinyISP programmer
|
||||
* usbtiny.c: New file.
|
||||
* usbtiny.h: (Ditto.)
|
||||
* Makefile.am: Include usbtiny into the build.
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the usbtiny support.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Sort list of supported programmers into
|
||||
alphabetical order, add all missing programmers.
|
||||
|
||||
2007-07-24 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Added long addresses to support devices with more
|
||||
than 64kB flash. Closes bug #20558: Long address problem with
|
||||
USBasp.
|
||||
|
||||
2007-06-27 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add ChangeLog-2004-2006.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.4.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix AVR910 devcodes. It seems that the AVR109
|
||||
listing refers to "BOOT"-type code, while the standard codes are
|
||||
different (usually one below).
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): only use the paged_load and
|
||||
paged_write backend functions iff the memory area in question has
|
||||
a page_size != 0.
|
||||
This is supposed to fix bug #19234: avrdude-5.3.1 segfaults when
|
||||
stk500v1 tries to program an ATtiny15
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Fall back to avr_{read,write}_byte_default(). Fixes
|
||||
bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
|
||||
programmer
|
||||
|
||||
2007-05-15 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* avrdude.conf.in: Rename the ATmega164 and ATmega324 into
|
||||
ATmega164P and ATmega324P, resp. Add an entry for the ATmega644P.
|
||||
Fixes bug #19769: ATmega164p not recognized
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (ser_send): Don't select() on the output fd before
|
||||
trying to write something to the serial line. That kind of
|
||||
polling isn't very useful anyway, and it seems it breaks for the
|
||||
Linux CP210x USB<->RS-232 bridge driver which is certainly a bug
|
||||
in the driver, but we can just avoid that bug alltogether.
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix the STK500v2 ISP delay parameter for
|
||||
ATmega640/1280/1281/2560/2561. Atmel has changed the XML
|
||||
files after the initial release.
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: -Oops - bug in verbose output. Fixed.
|
||||
-Fixed handling of cases where programmer cannot read fuses (AVR910)
|
||||
* main.c: -Also fixing handling of cases where programmer cannot
|
||||
read fuses
|
||||
This should close one or more bugs (18803, 19570)
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: Added verbose output from safemode routines.
|
||||
|
||||
2007-03-25 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* stk500generic.c: Forgot to close the serial port before trying to
|
||||
open it again, caused problems on Windows machines.
|
||||
Closes bug #19411
|
||||
|
||||
2007-02-26 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the AT90PWM2/3B devices.
|
||||
|
||||
2007-02-02 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Changed return value of function usbasp_initialize to stop
|
||||
avrdude on communication errors between programmer and target.
|
||||
Closes bug #18581: safemode destroys fuse bits
|
||||
|
||||
2007-02-01 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Remove duplicate definition of token K_WRITEPAGE
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Fix subdir handling. Now finally, "make
|
||||
distcheck" will include the documentation into the tarball even if
|
||||
the configure had been run without the --enable-doc.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* safemode.c: Obtain progname from avrdude.h rather than trying to
|
||||
roll our own (duplicate) copy of it.
|
||||
* avr910.c: Constify char pointers.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrpart.c: More backend/library abstraction and generalization:
|
||||
turn the list_parts() and list_programmers() functions into
|
||||
general list iteration functions that call a caller-supplied
|
||||
callback for each element. Implement list_parts() and
|
||||
list_programmers() as private functions in main.c based on that
|
||||
approach.
|
||||
* avrpart.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
|
||||
2007-01-25 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Rearrange everything so it is now built into a
|
||||
libavrdude.a library, and link main.c against that library.
|
||||
* configure.ac: Add AC_PROG_RANLIB as we are building a library
|
||||
now.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Major code cleanup.
|
||||
- Make all internal functions "static".
|
||||
- Make sure each module's header and implementation file match.
|
||||
- Remove all library-like functionality from main.c, so only
|
||||
the actual frontend remains in main.c.
|
||||
- Add C++ brackets to all header files.
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* avr910.h: (Ditto.)
|
||||
* avrdude.h: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* bitbang.h: (Ditto.)
|
||||
* butterfly.h: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* confwin.h: (Ditto.)
|
||||
* crc16.c: (Ditto.)
|
||||
* crc16.h: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* fileio.h: (Ditto.)
|
||||
* jtagmkI.h: (Ditto.)
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* lists.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppi.h: (Ditto.)
|
||||
* safemode.h: (Ditto.)
|
||||
* serbb.h: (Ditto.)
|
||||
* serial.h: (Ditto.)
|
||||
* stk500.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* term.h: (Ditto.)
|
||||
* usbasp.h: (Ditto.)
|
||||
* update.c: New file.
|
||||
* update.h: New file.
|
||||
* Makefile.am: Include update.c and update.h.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Move all "extern" declarations into a centreal header file.
|
||||
* Makefile.am: Add new avrdude.h.
|
||||
* avrdude.h: New file.
|
||||
* avr.c: Replace private extern decl's by #include "avrdude.h".
|
||||
* avr910.c: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* bitbang.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppiwin.c: (Ditto.)
|
||||
* ser_avrdoper.c: (Ditto.)
|
||||
* ser_posix.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500generic.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* usb_libusb.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8): Bump the delay values for flash
|
||||
and EEPROM, based on the current Atmel XML file.
|
||||
|
||||
2007-01-12 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Improve the detection of the Win32 HID library,
|
||||
and the presence of the header ddk/hidsdi.h. It now works
|
||||
correctly under Cygwin and several flavours of MinGW.
|
||||
* Makefile.am: Add new LIBHID pattern.
|
||||
|
||||
2007-01-11 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c (butterfly_initialize): when sending the 'T'
|
||||
command (which is ignored by current AVR109 bootloaders),
|
||||
send the first reply from the list of supported device
|
||||
codes back rather than using avrdude.conf's idea about
|
||||
an AVR910 device code. Apparently, this solves disagreements
|
||||
between different versions of at least the ATmega8 AVR910
|
||||
device code.
|
||||
Closes bug #18727: Writing flash failed
|
||||
|
||||
2007-01-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Reported by Till Harbaum:
|
||||
* avrdude.conf.in (ATtiny25/45/85): Change HVSP reset from
|
||||
500 microseconds to 1 ms, matching the most recent Atmel XML
|
||||
specs.
|
||||
185
src/avrdude/ChangeLog-2008
Normal file
185
src/avrdude/ChangeLog-2008
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
2008-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.h: Change the prototype for usleep() to be more Cygwin-
|
||||
friendly.
|
||||
* ppiwin.c: (Ditto.)
|
||||
|
||||
2008-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by limor <limor@ladyada.net>
|
||||
* usbtiny.c (usbtiny_cmd): Replace sizeof() by a fixed constant
|
||||
4 for the result array, because otherwise it would take the size
|
||||
of a pointer which miserably fails on 64-bit machines.
|
||||
|
||||
2008-11-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #6609: Using PCI parallel port cards on Windows
|
||||
* ppiwin.c (ppi_open): If the port parameter passed from the
|
||||
-p option is neither lpt1/2/3, try interpreting it directly as
|
||||
a base address.
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22882: Erase Cycle Counter does not work for stk500v2
|
||||
* stk500v2.c (stk500v2_chip_erase,stk500hv_chip_erase): Return
|
||||
the expected 0 for success rather than a protocol-dependant
|
||||
number.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22883: Chip Erase performed even with no-write flag (-n)
|
||||
* main.c: Do not erase the chip if both, -e and -n options have
|
||||
been specified.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #24589: AT90USB64* have wrong signature
|
||||
* avrdude.conf.in: Uncomment the correct, and delete the wrong
|
||||
signature for AT90USB646/647. Alas, the datasheet has never been
|
||||
corrected for years.
|
||||
|
||||
2008-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Fix a serious memory corruption that happened when
|
||||
using the JTAG ICE mkII (or AVR Dragon) in ISP mode. The wrong
|
||||
set of per-programmer private data had been allocated (stk500v2
|
||||
vs. jtagmkII) which was too small to hold the actual data.
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement Xmega JTAG support.
|
||||
* jtagmkII_private.h: Add EMULATOR_MODE_JTAG_XMEGA.
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Remember whether the device initialization worked, and
|
||||
allow to continue with -F if it failed yet do not attempt to
|
||||
perform anything on the device itself. That way, -tF could be
|
||||
specified for programmers like the STK500/STK600 even without a
|
||||
device connected, just in order to allow changing parameters on
|
||||
the programmer itself.
|
||||
* avrdude.1: Document that possible use of the -F option.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
|
||||
of the number of bytes to be written which caused a malloc chunk
|
||||
corruption.
|
||||
|
||||
2008-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First implementation of ATxmega support. By now, only the
|
||||
PDI mode of the STK600 is supported. Single-byte EEPROM
|
||||
(and flash) updates do not work yet.
|
||||
* avr.c: "boot" memory is a candidate memory region for paged
|
||||
operations, besides "flash" and "eeprom".
|
||||
* avrdude.conf.in: add ATxmega128A1 and ATxmega128A1revD
|
||||
* avrpart.h: add the AVRPART_HAS_PDI flag (used to distinguish
|
||||
ATxmega parts from classic AVRs), the nvm_base part field, and
|
||||
the offset field for a memory region.
|
||||
* config_gram.y: add "has_pdi", "nvm_base", and "offset"
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: disable auto_erase for ATxmega parts
|
||||
* stk500v2.c: implement the XPROG functionality, and divert to
|
||||
this for ATxmega parts
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a bunch of warnings.
|
||||
* avr910.c (avr910_paged_load): possible unitialized use of
|
||||
rd_size
|
||||
* jtagmkI.c (jtagmkI_initialize): pointer signedness mixup
|
||||
* jtagmkII.c (jtagmkII_print_parms1): propagate const'ness
|
||||
of parameter
|
||||
* usbasp.c (usbasp_transmit): pointer signedness mixup
|
||||
* ser_avrdoper.c (usbGetReport): remove useless pointer deref
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Ville Voipio:
|
||||
patch #6501: New autotools support for avrdude
|
||||
* Makefile.am: add @WINDOWS_DIRS@ to SUBDIR
|
||||
* bootstrap: allow for autconf-2.61 and automake-1.10, too
|
||||
* configure.ac: fix @WINDOWS_DIRS@ recursion, replace
|
||||
AC_PROG_CC by AM_PROG_CC_C_O, for esoteric reasons
|
||||
|
||||
2008-06-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Janos Sallai <janos.sallai@vanderbilt.edu>:
|
||||
patch #6074: added support for crossbow's MIB510 programmer
|
||||
* avrdude.conf.in: Add entry for mib510.
|
||||
* stk500.c: Add special hooks to handle the MIB510 programmer.
|
||||
It mostly talks STK500v1 protocol but has a special hello and
|
||||
goodbye sequence, and uses a fixed block size of 256 bytes.
|
||||
* doc/avrdude.texi: Document support for mib510.
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
* main.c: Realign verbose messages.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avr910.c: Print the device code selected in verbose mode.
|
||||
* butterfly.c: (Ditto.)
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
Add check for buffermode feature, and use it if present. Can be
|
||||
turned off using -x no_blockmode.
|
||||
* avr910.c: Implement buffermode test and usage.
|
||||
* avrdude.1: Document -x no_blockmode.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: #undef interface for Win32
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Add support for the -x devcode option.
|
||||
* avrdude.1: Document -x devcode for avr910.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add initial support for the Atmel STK600, for
|
||||
"classic" AVRs (AT90, ATtiny, ATmega) in both,
|
||||
ISP and high-voltage programming modes.
|
||||
* Makefile.am: Add -lm.
|
||||
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
|
||||
* config_gram.y: Add support for the stk600* keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* pgm.h: Add the "chan" parameter to set_varef().
|
||||
* stk500.c: (Ditto.)
|
||||
* serial.h: Add USB endpoint support to struct filedescriptor.
|
||||
* stk500v2.c: Implement the meat of the STK600 support.
|
||||
* stk500v2.h: Add new prototypes for stk600*() programmers.
|
||||
* stk500v2_private.h: Add new constants used in the STK600.
|
||||
* term.c: Add AREF channel support.
|
||||
* usb_libusb.c: Automatically determine the correct write
|
||||
endpoint ID, the STK600 uses 0x83 while all other tools use
|
||||
0x82. Propagate the EP to use through struct filedescriptor.
|
||||
* usbdevs.h: Add the STK600 USB product ID.
|
||||
* tools/get-stk600-cards.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the list of socket and routing
|
||||
card IDs, to be used in stk500v2.c (for displaying the
|
||||
names).
|
||||
* tools/get-stk600-devices.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the table of socket/routing cards
|
||||
and their respective AVR device support for doc/avrdude.texi.
|
||||
* avrdude.1: Document all the STK600 stuff.
|
||||
* doc/avrdude.texi: Ditto. Added a new chapter for
|
||||
Programmer Specific Information.
|
||||
|
||||
2008-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_recv): Make length computation unsigned so
|
||||
it cannot accidentally become negative.
|
||||
|
||||
411
src/avrdude/ChangeLog-2009
Normal file
411
src/avrdude/ChangeLog-2009
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
2009-11-09 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* fileio.c: ihex2bin did not properly handle files > 64K bytes
|
||||
* usb_libusb.c: re-enabled usb_reset for Macs (no reset causes lots of failures)
|
||||
* avrdude.1: spacing issue for avr32 fixed.
|
||||
|
||||
2009-11-09 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Implemented reset= and speed= extended parameters.
|
||||
* avrdude.1: Document the change.
|
||||
|
||||
2009-11-04 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* configure.ac, Makefile.am: Test if GCC accepts -Wno-pointer-sign
|
||||
|
||||
2009-11-04 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Implemented 'BinMode' support for
|
||||
firmware 2.7 and higher.
|
||||
* avrdude.1: Added info about BusPirate.
|
||||
|
||||
2009-11-03 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* arduino.c: Add on to bug #26703 / patch #6866 - clear DTR/RTS
|
||||
when closing the port.
|
||||
* Makefile.am: Silent warnings about signedness - they're useless
|
||||
and annoying, especially for 'char' vars.
|
||||
|
||||
2009-10-22 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* usb_libusb.c: disabled usb_reset for Macs (same as FreeBSD)
|
||||
|
||||
2009-10-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* main.c: Re-added default to serial port for BusPirate.
|
||||
|
||||
2009-10-12 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* main.c: removed some avr32 code that was pushed into jtagmkII.c
|
||||
* jtagmkII.c: consolodated the avr32 reset code and avr32_chipreset
|
||||
* avrpart.h: modified AVRPART flags for avr32
|
||||
* lexer.l: added is_avr32 flag - only way to get yacc code to set flag
|
||||
* avrdude.conf.in: updated avr32 section to include "is_avr32" flag
|
||||
|
||||
2009-10-12 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* config_gram.y: Restored inadvertantly removed buspirate entry
|
||||
* lexer.l: Restored inadvertantly removed buspirate entry
|
||||
|
||||
2009-10-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Replace GNU-only %as with %s in sscanf call.
|
||||
* ser_win32.c(ser_set_dtr_rts): Fixed typo in parameter name.
|
||||
* NEWS: Announce BusPirate.
|
||||
|
||||
2009-10-11 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
Support for AVR32
|
||||
|
||||
* AUTHORS: added myself
|
||||
* NEWS: announced AVR32 support
|
||||
* main.c: AVR32 flag tests to avoid several code blocks
|
||||
* fileio.c: mods to ihex read function to handle address offsets and
|
||||
size of avr32
|
||||
* jtagmkI.c: added cast to printf call to remove warning
|
||||
* arduino.c: added header file to bring in prototype for usleep()
|
||||
* config_gram.y: added defines for avr32, new jtag_mkii variant for avr32
|
||||
* jtagmkII_private.h: new jtag_mkii message types defined (used by
|
||||
avr32program)
|
||||
* jtagmkII.h: extern jtagmkII_avr32_initpgm() addition
|
||||
* jtagmkII.c: huge amount of code in support of avr32
|
||||
* avrpart.h: additional flags to AVRPART for avr32
|
||||
* usb_libusb.c: modified verbose test for USB read per-byte messages by
|
||||
by one, so with verbose=3 you get just full messages, 4 gives you bytes
|
||||
too
|
||||
* lexer.l: additions for avr32
|
||||
|
||||
2009-10-10 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
Support for Arduino auto-reset:
|
||||
* serial.h, ser_avrdoper.c, ser_posix.c, ser_win32.c: Added
|
||||
serial_device.set_dtr_rts implementations.
|
||||
* arduino.c, stk500.c, stk500.h: Call serial_set_dtr_rts()
|
||||
to reset Arduino board before program upload.
|
||||
Inspired by patch #6866, resolves bug #26703
|
||||
|
||||
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Optimised buspirate_cmd() - reading 1kB EEPROM now
|
||||
takes only 14 sec instead of almost 2 mins with the original
|
||||
implementation.
|
||||
|
||||
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c, buspirate.h: Support for the BusPirate programmer
|
||||
* config_gram.y, avrdude.conf.in, main.c, lexer.l, Makefile.am:
|
||||
Glue for BusPirate.
|
||||
|
||||
2009-08-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_close): Repair the logic around the
|
||||
conditional compilation of usb_reset() introduced in r798.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: We are post-5.8 now.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.8
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Roger Wolff:
|
||||
bug #26527: bug in unicode conversion
|
||||
* ser_avrdoper.c (convertUniToAscii): when encountering a UTF-16
|
||||
character that cannot be converted to ASCII, increment the UTF-16
|
||||
pointer anyway when proceeding.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkI.c (jtagmkI_send): Replace %zd format by %u since not all
|
||||
implementations do understand the C99 formatting options (sigh).
|
||||
* jtagmkII.c (jtagmkII_send): (Ditto.)
|
||||
* stk500v2.c (stk500v2_recv): (Ditto.)
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26002: HVPP of EEPROM with AVR Dragon and ATmega8 Fails
|
||||
* avrdude.conf.in (ATmega8): add page size for EEPROM.
|
||||
|
||||
2009-07-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Fix a serious memory corruption problem resulting
|
||||
out of the chaining of both, the stk500v2 and the jtagmkII
|
||||
programmers for some programming hardware (JTAG ICE mkII and AVR
|
||||
Dragon running in ISP, HVSP or PP mode), where both programmers
|
||||
have to maintain their private programmer data.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Post-release (is pre-release...)
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.7
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add my name to the copyright output when being verbose.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Shaun Jackman <sjackman@gmail.com>
|
||||
bug #21798: Fix both XSLT scripts
|
||||
* tools/get-dw-params.xsl (format-hex): Add the parameter count.
|
||||
* tools/get-hv-params.xsl (format_cstack): Ditto.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #21922: ATmega163 still not working in version 5.5
|
||||
* avrdude.conf.in (atmega163): fill in stk500v2 parameters, correct
|
||||
some flash programming parameters as well.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22206: avrdude: ser_setspeed(): tcsetattr() failed
|
||||
* ser_posix.c (ser_setspeed): Don't pass TCSAFLUSH to tcsetattr() as
|
||||
it apparently fails to work on Solaris. After reading the
|
||||
documentation again, it seems TCSAFLUSH and TCSANOW are indeed
|
||||
mutually exclusive.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22234: WINDOWS version: HOWTO: Specify Serial Ports Larger than COM9
|
||||
* ser_win32.c (ser_open): prepend \\.\ to any COM port name, so it is
|
||||
safe to be used for COM ports above 9.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26408: Crash in stk500v2_open()
|
||||
* stk500generic.c: Implement setup and teardown hooks, calling in turn
|
||||
the respective hooks of the stk500v2 implementation.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26130: Avrdude doesn't display it's version.
|
||||
* main.c (usage): add a version number display to the default usage
|
||||
message.
|
||||
|
||||
2009-07-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26412: avrdude segfaults when called with a programmer that does not
|
||||
support it
|
||||
* main.c: do not call pgm->perform_osccal() unless it is != 0.
|
||||
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Zoltan Laday:
|
||||
patch #6825: xmega problems with JTAGICEmkII
|
||||
* jtagmkII.c: Many fixes for Xmega devices.
|
||||
* jtagmkII_private.h: Add various new constants required for
|
||||
Xmega devices.
|
||||
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
|
||||
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
|
||||
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
|
||||
ATXMEGA64A4, ATXMEGA128A4
|
||||
* avr.c (avr_read, avr_write): Add more names for (Xmega)
|
||||
memory areas that require paged operation.
|
||||
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_write_byte): Handle writing fuse bytes.
|
||||
|
||||
2009-04-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Carl Hamilton:
|
||||
* update.c (parse_op): correctly \0-terminate buf after filling
|
||||
it, before it is potentially used as the source of a call to
|
||||
strlen or strcpy.
|
||||
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Merge the -P 0xXXX option description from
|
||||
avrdude.1.
|
||||
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: declare AM_PROG_CC_C_O to avoid the warning
|
||||
"compiling `config_gram.c' with per-target flags
|
||||
requires `AM_PROG_CC_C_O' in `configure.ac'"
|
||||
|
||||
2009-03-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #25971: "error writing to <stdout>" with multiple -U params.
|
||||
* fileio.c: Do not close the input/output stream when working on an
|
||||
stdio stream.
|
||||
|
||||
2009-02-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Based on patch #6484 commited by Jurgis Brigmanis:
|
||||
* usbasp.c: added software control for ISP speed
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2009-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c (avr910_read_byte_flash): Eliminate a static variable that
|
||||
hasn't been in use for 5 years.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Post-release 5.6.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.6.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Ed Okerson:
|
||||
* jtagmkII.c (jtagmkII_read_byte): Fix signature reading of
|
||||
Xmega.
|
||||
|
||||
2009-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Mikael Hermansson:
|
||||
* avrdude.conf.in (ATxmega256A3): new device.
|
||||
* stk500v2 (stk500v2_initialize): Enable the AVRISPmkII as a
|
||||
PDI-capable device for ATxmega parts.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lars Immisch:
|
||||
patch #6750: Arduino support - new programmer-id
|
||||
* arduino.c: New file, inherits stk500.c.
|
||||
* arduino.h: New file.
|
||||
* Makefile.am: Add arduino.c and arduino.h.
|
||||
* config_gram.y: Add arduino keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* avrdude.1: Document the new programmer type.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Turn all non-const static data into instance data.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Move term.[ch] from the library into the CLI
|
||||
application section, as it is not useful for anything else but
|
||||
the CLI frontend.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega1284P): new device.
|
||||
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
More fixes for Solaris, including fixes for the Sunpro compiler:
|
||||
* avr.h: Remove stray semicolon.
|
||||
* configure.ac: Add check for predefined types uint_t and ulong_t.
|
||||
* confwin.c: Include "avrdude.h" on top to avoid empty translation
|
||||
unit warning.
|
||||
* ppwin.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* jtagmkII.c (jtagmkII_recv): remove unreachable "return".
|
||||
* stk500.c (stk500_initialize): (Ditto.)
|
||||
* par.c: Test for both, __sun__ and __sun to see whether we are
|
||||
being compiled on Solaris.
|
||||
* ppi.c: (Ditto.)
|
||||
* stk500v2.c: Implement the DEBUG and DEBUGRECV macros in a way
|
||||
that is compatible with the ISO C99 standard.
|
||||
* usbtiny.c: Only typedef uint_t and ulong_t if they have not
|
||||
been found already by the autoconf checks.
|
||||
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22204: Solaris10/11 Undefiniertes Symbol gethostbyname socket
|
||||
connect
|
||||
* configure.ac: Add checks for gethostent() and socket().
|
||||
While being here, remove some old cruft left from ancient days.
|
||||
|
||||
2009-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Bump the %p size so AT&T lex will continue to work.
|
||||
|
||||
2009-02-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
(Partially) submitted by John Voltz:
|
||||
bug #20004: AVRDUDE update (-U) operations do not close files
|
||||
* fileio.c (fmt_autodetect, fileio): fclose() files.
|
||||
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbtiny.c: Replace all but one (very unlikely to trigger) exit(1)
|
||||
by return -1.
|
||||
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Dick Streefland:
|
||||
patch #6749: make reading from the USBtinyISP programmer more robust
|
||||
* usbtiny.c: Add code to retry failed communication attempts.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nick Hibma:
|
||||
bug #22271: usb_reset in usb_libusb.c not necessary in FreeBSD 6.x
|
||||
* usb_libusb.c (usbdev_close): Do not call usb_reset() on FreeBSD.
|
||||
It is not necessary there.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Andrew O. Shadoura:
|
||||
bug #25156: add direct SPI transfer mode
|
||||
* bitbang.c: Implement direct SPI transfers.
|
||||
* bitbang.h: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* term.c: Add the "spi" and "pgm" commands.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Limor ("Lady Ada"):
|
||||
bug #24749: add support for '328p
|
||||
* avrdude.conf.in (ATmega328P): new device support.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by "Womo":
|
||||
bug #25241: AT90USB162, AT90USB82 device support patch for avrdude-5.5
|
||||
(also: bug #21745: AT90USBxx2 support)
|
||||
* avrdude.conf.in (AT90USB162, AT90USB82): new device support.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Evangelos Arkalis:
|
||||
patch #6069: Atmel AT89ISP Cable
|
||||
* avrdude.conf.in (89isp): new programmer support.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Bob Paddock:
|
||||
patch #6748: ATTiny88 Config
|
||||
* avrdude.conf.in (ATtiny88): new device support.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Mark Litwack:
|
||||
patch #6261: avrdude won't use dragon/debugwire to write a file
|
||||
to eeprom
|
||||
* jtagmkII.c (jtagmkII_paged_write): when in debugWire mode,
|
||||
implement a paged write to EEPROM as a series of byte writes.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Janos Sallai:
|
||||
patch #6542: paged_load fails on the MIB510 programming board
|
||||
* stk500.c: Add a workaround for the different signon sequence on
|
||||
MIB510 programmers.
|
||||
|
||||
2009-02-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the ATmega128RFA1.
|
||||
* avrdude.1: document the addition of ATmega128RFA1.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
354
src/avrdude/ChangeLog-2010
Normal file
354
src/avrdude/ChangeLog-2010
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
2010-12-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega128RFA1): Bump two timing values in order to
|
||||
improve ISP programming stability, in particular with the STK600.
|
||||
|
||||
2010-12-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_command): Detect warning status codes.
|
||||
|
||||
2010-10-22 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* serial.h: serial_open() calls will now return -1 on error (no call to exit())
|
||||
* buspirate.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* arduino.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2010-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30566: MinGW + Ubuntu 9.04
|
||||
* stk500v2.c (stk500v2_open): use same condition to refer to the AVR
|
||||
Doper support as used in the definition in ser_avrdoper.c.
|
||||
(Thanks to Christian Starkjohann for the analysis of the problem.)
|
||||
|
||||
2010-07-19 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Added compatibility with BusPirate "NewUI" firmware 5.x
|
||||
(contributed by Kari Knuuttila)
|
||||
|
||||
2010-07-12 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* avrdude.conf.in (atmega88p): New device.
|
||||
|
||||
2010-06-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29913: 246 Byte Bug - AVRdude crashes
|
||||
doc/avrdude.texi (Troubleshooting): Mention the libusb 0.1 API
|
||||
wrapper issue that is present in some Linux versions.
|
||||
|
||||
2010-03-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29263: Can't build avrdude on windows using latest cygwin 1.7.1
|
||||
* doc/avrdude.texi: Remove the recommendation for building
|
||||
Win32 binaries under Cygwin; mention MinGW as an alternative
|
||||
environment.
|
||||
|
||||
2010-03-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* ser_posix.c(ser_set_dtr_rts): Fixed DTR on/off to make
|
||||
Arduino auto-reset work. (bug #29108, patch #7100)
|
||||
|
||||
2010-03-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Replace printf() by fprintf(stderr)
|
||||
* safemode.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2010-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Cleanup Cygwin builds.
|
||||
* windows/Makefile.am (loaddrv_LDFLAGS): remove, the -mno-cygwin
|
||||
flag is supposed to be set in CFLAGS by ./configure
|
||||
* configure.ac: add a check for the presence of usleep(), add a
|
||||
check whether the linker accepts -static
|
||||
* avrdude.h: protect prototype for usleep by !defined(HAVE_USLEEP)
|
||||
* ppwin.c (usleep): protect by !defined(HAVE_USLEEP)
|
||||
* main.c: silence "array subscript of type char" compiler warnings
|
||||
by casting all arguments to tolower()/toupper() and isspace()/
|
||||
isdigit()/ispunct() to "int"
|
||||
* butterfly.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-5.10.
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 5.10.
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28677: Cygwin's GCC no longer supports -mno-cygwin option
|
||||
* configure.ac: For Win32 environments, add a check whether the
|
||||
compiler understands the -mno-cygwin option. If not, don't use
|
||||
it but suggest using a different compiler.
|
||||
|
||||
2010-01-18 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
bug #28660: Problem with loading intel hex rom files that exceed
|
||||
0x10000 bytes
|
||||
* fileio.c: Fix two byte shifts.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Michael biebl:
|
||||
* configure.ac: Fix FreeBSD default serial port name.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: If entering JTAG mode fails with a bad JTAG ID
|
||||
message, retry with external reset applied (in case the target
|
||||
is in sleep mode or has asserted the JTD bit).
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Aurelien Jarno:
|
||||
* configure.ac: Fix build for GNU/kFreeBSD.
|
||||
* ppi.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for post-5.8.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for release 5.8.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Soren Jorvang:
|
||||
bug #28611: -i delay not being applied to all serial port
|
||||
bit banging state transitions
|
||||
* serbb_win32.c: Apply ispdelay everywhere.
|
||||
* serbb_posix.c: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h: Implement TPI mode for AVRISPmkII/STK600
|
||||
* config_gram.y: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in: Add ATtiny4/5/9/10
|
||||
* avrdude.1: Document TPI and new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by clint fisher:
|
||||
patch #7038: Adding Atmega32U4 Device to avrdude.conf.in
|
||||
* avrdude.conf.in (atmega32u4): New device.
|
||||
* avrdude.1: Document the new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Thomas Pircher:
|
||||
patch #6927: Documentation patches
|
||||
* doc/avrdude.texi: Fix various typos, and remove the last
|
||||
remnants of obsoleted options -i/-o/-m/-f.
|
||||
* avrdude.1: Merge typo fixes from avrdude.texi where
|
||||
applicable.
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Update documentation to match the reality (device
|
||||
support, memory areas).
|
||||
* doc/avrdude.texi: Update documentation to match the
|
||||
reality (device support, programmer support, memory areas).
|
||||
Merge buspirate-specific comments from avrdude.1.
|
||||
* jtagmkII.c: Add some firmware feature checks.
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement PDI mode support for the JTAG ICE mkII
|
||||
and the AVR Dragon.
|
||||
* jtagmkII.h: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* jtagmkII_private.h: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Update STK600 routing and socket card data from XML
|
||||
file.
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Cleanup the open/close handling to avoid accessing
|
||||
unallocated memory (in the atexit handler) in case of bailing out.
|
||||
* main.c: (Ditto.)
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Stylistic changes: move #defines out into
|
||||
jtagmkII_private.h, drop all #if 0 blocks, fold overly long lines,
|
||||
move the *_initpgm() functions to the end of the file; while being
|
||||
here, remove all trailing whitespace.
|
||||
* jtagmkII_private.h: move AVR32 #defines here.
|
||||
|
||||
2010-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bootstrap: autoconf 2.62 works well.
|
||||
|
||||
2010-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Various fixes for Xmega devices.
|
||||
* avrdude.conf.in: Correctly declare EEPROM page sizes for
|
||||
all Xmega devices (0x20 instead of 0x100).
|
||||
* avr.c: If a memory region has a page size declared, try
|
||||
using the paged IO routines regardless of the target memory
|
||||
name. Xmega EEPROM requires to be written in paged mode.
|
||||
Correctly use a long (rather than unsigned long) variable to
|
||||
evaluate the success status of the paged mode write attempt.
|
||||
* stk500v2.c: Don't apply TIF space offsets twice (bug #27995:
|
||||
AVRDUDE 5.8svn fails to program and read XMEGA); use
|
||||
stk500v2_loadaddr() prior to paged mode (EEPROM and flash) writes,
|
||||
otherwise programming of flash areas will fail; while being there,
|
||||
check the return value of stk500v2_loadaddr() everywhere; use the
|
||||
correct write/erase mode bits (same as AVR Studio does).
|
||||
|
||||
2010-01-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Initialise firmware version to v0.0
|
||||
prior to parsing the buspirate banner.
|
||||
|
||||
2010-01-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Clean-up the Xmega erase functions.
|
||||
* jtagmkII_private.h: Add CMND_XMEGA_ERASE as well as
|
||||
the various XMEGA_ERASE_* definitions (from updated
|
||||
appnote AVR067)
|
||||
* jtagmkII.c (jtagmkII_chip_erase): Correctly implement Xmega chip
|
||||
erase based on CMND_XMEGA_ERASE. After erasing an Xmega part, do
|
||||
*not* reinitialize the world, as a subsequent programming
|
||||
operation will fail (for unknown reasons). Actually, this was
|
||||
really only required for ancient AVRs, but doesn't hurt on mega
|
||||
and tiny devices.
|
||||
* jtagmkII.c (jtagmkII_pre_write): Remove, this turned out
|
||||
to be just a chip erase.
|
||||
* jtagmkII.c (jtagmkII_program_disable): Don't try reading
|
||||
"hfuse" for Xmega parts; they don't have it.
|
||||
* main.c (main): Re-enable auto-erase. It's been done
|
||||
before (as "jtagmkII_pre_write") in jtagmkII_paged_write()
|
||||
anyway. Xmega boot and application flash areas should be
|
||||
handled separately in the future, so auto_erase can only
|
||||
affect the area just being programmed.
|
||||
|
||||
2010-01-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c (main): disable safemode for Xmega parts.
|
||||
|
||||
2010-01-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: If the BusPirate doesn't respond
|
||||
to a standard a reset command assume it was in binmode
|
||||
and attempt to exit to text mode first.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bitbang.c: Fix Win32 build error: move freq up to the file
|
||||
level.
|
||||
* buspirate.c: Fix Win32 build warning: include <malloc.h> to
|
||||
to get a declaration for alloca().
|
||||
|
||||
2010-01-08 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
bug #28520: Programming with USBasp with low clock speed fails
|
||||
* usbasp.c: Change blocksize depending on sck frequency to
|
||||
avoid usb transmition timeouts.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #27505: serbb_posix does not cope with inverted pins
|
||||
* serbb_posix (serbb_highpulsepin): apply PIN_MASK when
|
||||
checking pin numbers.
|
||||
* serbb_win32 (serbb_highpulsepin): (Dito.)
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28516: Linux/Dragon: Error message on exit
|
||||
* stk500v2.c: Fix the "bad response to GO command:
|
||||
RSP_ILLEGAL_EMULATOR_MODE" message. jtagmkII_close()
|
||||
has been called with the wrong pgm->cookie. Wrap it
|
||||
inside stk500v2_jtagmkII_close(), adjusting the cookie
|
||||
data appropriately.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Doug:
|
||||
patch #7010: Win32 enhanced bitbang_delay
|
||||
* bitbang.c (bitbang_calibrate_delay, bitbang_delay): On Win32,
|
||||
use the high-resolution performance counter rather than the
|
||||
uneducated delay loop guess if it is available on the target
|
||||
hardware.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Gerard:
|
||||
patch #6828: Using arbitrary BAUD rates
|
||||
* ser_posix.c (serial_baud_lookup): Allow non-standard baud
|
||||
rates.
|
||||
* ser_win32.c (serial_baud_lookup): (Dito.)
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Eric Trein:
|
||||
bug #27596: AT90s2333 is not correctly supported in avrdude.conf
|
||||
* avrdude.conf.in (at90s2333): add various STK500v2 parameters.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Gyorgy Szekely:
|
||||
bug #28458: Buffer line is incorrectly released for PP programmers
|
||||
* par.c (par_close): use par_setmany() rather than par_setpin()
|
||||
for PPI_AVR_BUFF.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lukasz Goralczyk:
|
||||
bug #27507: SIGSEGV when using avrdragon (avrdude 5.8)
|
||||
* stk500v2.c (stk500v2_dragon_isp_initpgm): Use
|
||||
stk500v2_jtagmkII_setup/stk500v2_jtagmkII_rather than their
|
||||
jtagII counterparts, to get the private data properly
|
||||
initialized.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Cosmetics: remove UTF-8 dashes, adjust for 8-column
|
||||
hard tabs.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: add $ Id $ line.
|
||||
* buspirate.h: add $ Id $ line.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a few warnings that came up recently (some of them only triggered
|
||||
by recent GCC versions).
|
||||
* config_gram.y (parse_cmdbits): "brkt possibly used uninitialized"
|
||||
(GCC errs here)
|
||||
* jtagmkII.c (jtagmkII_reset32): "status possibly used uninitialized"
|
||||
(I think GCC errs, too)
|
||||
* buspirate.c: "pointers differ in signedness" (mismatch between
|
||||
string processing and the use of "unsigned char" throughought the
|
||||
AVRDUDE API)
|
||||
|
||||
2010-01-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_smc_init32): replace sleep() by usleep() for
|
||||
win32 compatibility.
|
||||
489
src/avrdude/ChangeLog-2011
Normal file
489
src/avrdude/ChangeLog-2011
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
2011-12-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Added is_at90s1200 option to part description
|
||||
* doc/avrdude.texi: Added missing options to part definition
|
||||
* config_gram.y: Fixed resetting of is_at90s1200 and is_avr32 flags
|
||||
|
||||
2011-12-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7693: Fix config file atmel URLs
|
||||
* avrdude.conf.in: Updated URLs
|
||||
* avrpart.h: Updated URLs
|
||||
* doc/avrdude.texi: Updated URLs
|
||||
|
||||
2011-12-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (baud_lookup_table): Conditionalize the inclusion of
|
||||
non-standard baud rates (only baud rates up to B38400 are
|
||||
standardized by the Single UNIX Specification).
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: Added part parent rule and allow overwriting existing
|
||||
data at several places
|
||||
* avrdude.conf.in: Added description comment and m328/m328p as example
|
||||
* avrpart.c: avr_dup_mem-functions now copy buf and tags memory block
|
||||
only they are already allocated.
|
||||
* lexer.l: Added parent as valid token
|
||||
|
||||
(not in original patch)
|
||||
* avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part-
|
||||
functions now duplicate the opcodes in their op-array to avoid memory leaks.
|
||||
* doc/avrdude.texi: Added description of part parent feature
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the parts lists, programmers lists follows later)
|
||||
* doc/Makefile.am: Add rule how to create avrdude before generating parts list
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the parts lists, programmers lists follows later)
|
||||
* doc/avrdude.texi: Add include of generated table of parts
|
||||
* doc/Makefile.am: Add generating of table of parts in parts.texi
|
||||
* doc/parts_comments.txt: Adding file containing part commenz references
|
||||
* avrdude.1: Remove table of parts and mention "-p ?" option
|
||||
* avrpart.c: Use AVR_DESCLEN for strncasecmp at list sorting
|
||||
|
||||
2011-12-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: Add writing of definition of confsubst to config.status,
|
||||
so it can run alone, not only called by configure.
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7680: Fixing timeout problem in ser_recv in ser_win32.c
|
||||
* ser_win32.c: Return -1 at timeout in ser_recv().
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y: Fixed another memory leak, when define an operation
|
||||
more than once
|
||||
* avrdude.conf.in: Fixed double definition at ATmega6490
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y: Restructuring and compacting programmer definition
|
||||
part of grammar (in preparation of patch #7688)
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Update documentation of programmer definition
|
||||
* doc/avrdude.texi: Update documentation of programmer definition
|
||||
and add list of implemented programmer types
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7667: Minor memory handling fixes
|
||||
* config_gram.y: Added several free_token() calls.
|
||||
|
||||
2011-12-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7671: Sorting programmers and parts lists for console output
|
||||
* avrdude.conf.in: change part desc of several parts to common pattern
|
||||
AT(mega|tiny|xmega)[0-9]+[A-Z]* (Upper case AT, lower case in middle)
|
||||
* list.[ch]: added sorting function lsort()
|
||||
* pgm.[ch]: added function sort_programmers()
|
||||
* avrpart.[ch]: added function sort_avrparts()
|
||||
* main.c: use sort functions in list_programmers() and list_parts()
|
||||
* main.c: list functions show config file info only at verbose mode
|
||||
|
||||
2011-10-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Replace "cvs" in version number by "svn".
|
||||
|
||||
2011-10-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34518: loading intel hex files > 64k using record-type 4
|
||||
(Extended Linear Address Record)
|
||||
fileio.c: Replace the change from r928 (handling of 0x8000000
|
||||
offset in AVR32 files) by a completely different logic that no
|
||||
longer breaks hex files for other devices starting with an
|
||||
offset; also apply a similar change to S-record files, as well
|
||||
as when writing files.
|
||||
fileio.c: (Ditto.)
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrftdi.c: Remove stray printf()s by fprintf(stderr)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Restrict the cyclecounter readout to those cases where
|
||||
it has been explicitly requested (by -y or -Y), rather than always
|
||||
attempting to read the last EEPROM bytes.
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_load, stk600_xprog_paged_write):
|
||||
Fix regression in the AVRISPmkII/STK600 TPI handling introduced
|
||||
by the USBasp's TPI implementation which added a pagesize even for
|
||||
the minor memory regions of TPI devices. Also fix wrong offset
|
||||
introduced by the memory tagging patch.
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): Don't bail out on TPI parts if
|
||||
their programmer doesn't provide a (low-level) cmd_tpi method;
|
||||
instead, fall back to the normal programmer methods which are
|
||||
supposed to handle the situation.
|
||||
This fixes a regression where the recent bitbang-TPI implementation
|
||||
broke TPI handling of STK600/AVRISPmkII.
|
||||
|
||||
2011-09-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Mega-commit to bring in memory tagging.
|
||||
Each memory image byte is now tagged as it's being read from a file.
|
||||
Only bytes read from a file will be written or verified (modulo page
|
||||
granularity requirements).
|
||||
* avrpart.h: Add memory tags.
|
||||
* avrpart.c: Allocate and initialize tag area.
|
||||
* update.h: Drop unused parameter "verify" from do_op().
|
||||
* pgm.h: Add parameter base_addr to the paged_load and paged_write
|
||||
methods, respectively.
|
||||
* avr.h: New parameter to avr_read: second AVRPART to verify against.
|
||||
* fileio.c: Track all memory regions that have been read from an
|
||||
input file by tagging them.
|
||||
* update.c: Call avr_read() with the new parameter list.
|
||||
* main.c: Call avr_initmem() to initialize the memory regions, rather
|
||||
than trying to duplicate an unitialized part, and then let the
|
||||
original part rot away.
|
||||
* avr.c: Implement the heart of the new featureset. For paged memory
|
||||
areas, when writing or verifying, call the paged_write and paged_load
|
||||
methods, respectively, once per page instead of on the entire memory.
|
||||
When writing, only write bytes or pages that have content read from a
|
||||
file. Whe verifying, only read memory bytes or pages where the
|
||||
verification data have been read from a file. Only verify those bytes
|
||||
that have been read from a file.
|
||||
* avrftdi.c: Implement the new API for paged_load and paged_write,
|
||||
respectively.
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2011-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_command): Treat warnings as errors rather than
|
||||
success.
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 3 - documentation)
|
||||
* avrdude.1: Document the programmer type restrictions for AT90S1200
|
||||
devices.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 2 - stk500v2 and relatives)
|
||||
* stk500v2.c (stk500v2_initialize): For the AT90S1200, release
|
||||
/RESET for a moment before reinitializing, as this is required by
|
||||
its programming protocol.
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: In AC_CHECK_LIB for libftdi, check for
|
||||
ftdi_usb_get_strings() rathern than ftdi_init(), as this is a more
|
||||
specific thing to search for in order to make sure getting a
|
||||
recent enough libftdi.
|
||||
|
||||
2011-08-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 1 - bitbang
|
||||
programmers)
|
||||
* config_gram.y: Introduce new keyword "is_at90s1200".
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Applew new keyword to the AT90S1200 device.
|
||||
* avrpart.h: Introduce new flag AVRPART_IS_AT90S1200, reflecting
|
||||
the is_at90s1200 configuration keyword.
|
||||
* bitbang.c (bitbang_initialize): Replace existing test for
|
||||
AT90S1200 by AVRPART_IS_AT90S1200
|
||||
* avr.c (avr_write_byte_default): Avoid the pre-write reading for
|
||||
the AT90S1200, as this appears to sometimes corrupt the high byte
|
||||
by pre-programming the low byte just written into it.
|
||||
|
||||
2011-08-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for post-5.11.
|
||||
|
||||
2011-08-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for releasing AVRDUDE 5.11.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Update the list of supported AVR devices.
|
||||
* doc/avrdude.texi: (Ditto).
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: add -lusb as "other libraries" when checking
|
||||
for libftdi.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Juergen Weigert:
|
||||
patch #7056: adding support for mikrokopter bootloader to butterfly
|
||||
* butterfly.c: Add some specific logic to handle the
|
||||
mikrokopter.de butterfly bootloader.
|
||||
* butterfly.h: Add one related function declaration.
|
||||
* config_gram.y: Add butterfly_mk keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add entry for butterfly_mk.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Stefan Tomanek:
|
||||
patch #7542: add default_bitclock to configuration files
|
||||
* config.c: Add the new keyword and its handling.
|
||||
* config.h: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Brett Hagman:
|
||||
patch #7603: wiring - programmer type for Wiring boards
|
||||
(based on STK500v2)
|
||||
* wiring.c: New file.
|
||||
* wiring.h: (Ditto.)
|
||||
* Makefile.am: Add new files.
|
||||
* stk500v2_private.h: Reorganize so some functions and struct
|
||||
pdata are globally known.
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* lexer.l: Add new programmer keywords.
|
||||
* config_gram.y: (Ditto.)
|
||||
* avrdude.conf.in: Add "wiring" programmer entry.
|
||||
* avrdude.1: Document the new programmer.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
* AUTHORS: Add Brett Hagman.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by an anonymous contributor on the mailinglist:
|
||||
* avrdude.conf (jtagkey): Add a definition for the Amontec
|
||||
JTAGKey
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Juergen Weigert:
|
||||
bug #22720: avrdude-5.5 ignores buff settings in avrdude.conf
|
||||
(Note that the actual bug the subject is about has been fixed
|
||||
long ago.)
|
||||
* update.c (do_op): fix a diagnostic message
|
||||
* pgm.h: add exit_datahigh field
|
||||
* par.c: set and act upon the exit_datahigh field
|
||||
* avrdude.1: document the new -E options
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #33811: Parallel make fails
|
||||
* Makefile.am (BUILT_SOURCES): Add this macro.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #33114: Segfault after setting the DWEN fuse with Dragon
|
||||
* jtagII.c (jtagmkII_getsync): Instead of exit()ing from
|
||||
deep within the tree when detecting the "need debugWIRE"
|
||||
situation, properly pass this up as a return code.
|
||||
* jtagII_private.h (JTAGII_GETSYNC_FAIL_GRACEFUL): New constant.
|
||||
* stk500v2.c (stk500v2_jtagmkII_open): Don't tell anything
|
||||
anymore when receiving a JTAGII_GETSYNC_FAIL_GRACEFUL from
|
||||
jtagmkII_getsync(); silently give up (all necessary has been
|
||||
said already).
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Jason Hecker:
|
||||
* usbasp.c (libusb_to_errno): Conditionalize some error codes
|
||||
that apparently are lacking on MinGW.
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix warnings.
|
||||
* ser_avrdoper.c: add <stdlib.h> so exit() is declared.
|
||||
* usbtiny.c (usbtiny_open): provide an initializer to a
|
||||
"may be used uninitialized" variable (since GCC could not
|
||||
fully detect the logic behind).
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Add a check for FreeBSD's libusb-1.0
|
||||
compatible library that is found in libusb.a/.so on
|
||||
FreeBSD 8+.
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Doug Springer, based on work by
|
||||
Wolfgang Moser, Ville Voipio, Hannes Weisbach
|
||||
patch #7486: Patch to add FT2232C/D, FT2232H, FT4232H,
|
||||
usbvid, usbpid, usbdev for USB support - Based on #7062
|
||||
* avrftdi.c: New file.
|
||||
* avrftdi.h: (Ditto.)
|
||||
* configure.ac: Add check for libftdi.
|
||||
* config_gram.y: Add AVRFTDI and per-programmer USB string
|
||||
keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add avrftdi and 2232HIO programmers.
|
||||
* pgm.h: Add USB parameters.
|
||||
* Makefile.am: Add avrftdi.c and avrftdi.h.
|
||||
* AUTHORS: Mention the new authors.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29585: Fix license
|
||||
* doc/avrdude.texi: Add FDL as an option to the licensing
|
||||
statement, as the savannah administration would like it
|
||||
that way.
|
||||
|
||||
2011-08-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Darell Tan:
|
||||
patch #7244: TPI bitbang implementation
|
||||
* bitbang.c: Add TPI bitbang stuff.
|
||||
* bitbang.h: (Ditto.)
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: Wire bitbang_cmd_tpi into the struct pgm.
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* doc/avrdude.texi: Document the TPI bitbang support.
|
||||
|
||||
2011-08-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Grygoriy Fuchedzhy:
|
||||
bug #31779: Add support for addressing usbtinyisp with -P option
|
||||
* usbtiny.c (usbtiny_open): Add logic to distinguish multiple USBtinyISP
|
||||
programmers by their bus:device tuple.
|
||||
* doc/avrdude.texi: Document the new functionality.
|
||||
* avrdude.1: (Ditto.)
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Timon Van Overveldt:
|
||||
bug #30268: Debugwire broken in avrdude-5.10
|
||||
* jtagmkII.c (jtagmkII_initialize): only try setting up a JTAG chain when
|
||||
the programmer is using JTAG.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29636: AVRDude issues invalid CMD_CHECK_TARGET_CONNECTION
|
||||
on the AVRISP-MKII
|
||||
* stk500v2.c (stk500v2_program_enable): Rewrite the logic to
|
||||
explain ISP activation failures.
|
||||
* stk500v2_private.h: Fix the various STATUS_* constants;
|
||||
AVR069 and AVR079 disagreed in their values, even though they
|
||||
are apparently implementing the same logic behind.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29650: Programming timeouts in ATmega128RFA1 are too slow
|
||||
* avrdude.conf.in (ATmega128RFA1): Bump write delay values for flash and
|
||||
EEPROM to 50 ms.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8515, ATmega8535, ATmega48, ATmega88, ATmega88P,
|
||||
ATtiny88, ATmega168, ATmega168P, ATmega328P): Bump delay value for STK500v2
|
||||
EEPROM write operation to 5, according to the respective XML files.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Darcy Houlahan:
|
||||
bug #29694: error in avrdude.conf for attiny84 eeprom
|
||||
* avrdude.conf.in (ATtiny84, ATtiny85): fix A7 bit in EEPROM write
|
||||
command.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Durant Gilles:
|
||||
* avrdude.conf.in (ATtiny4313): Fix flash addressing bits for manual ISP
|
||||
algorithm.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Philip:
|
||||
bug #31386: A "BUILD.svn" or similar "how to get started" doc would be helpful
|
||||
* BUILD-FROM-SVN: New file.
|
||||
|
||||
2011-08-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nic Jones:
|
||||
bug #32539: [Documentation][Patch] Man page is misleading
|
||||
re: Dragon & PDI
|
||||
* doc/avrdude.texi: Update information about PDI connections
|
||||
on AVR Dragon
|
||||
|
||||
2011-08-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add <stdint.h> so this actually compiles
|
||||
again.
|
||||
|
||||
2011-08-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by tixiv@gmx.net:
|
||||
bug #33345: File auto detection as binary doesn't open
|
||||
file in binary mode on Windows
|
||||
* fileio.c: Move the decision about opening files in
|
||||
binary mode until before the fopen() call.
|
||||
|
||||
2011-06-16 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Fix part id of ATtiny9.
|
||||
|
||||
2011-05-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Based on patch #7440 commited by Slawomir Fraś:
|
||||
* usbasp.c: added TPI support for USBasp
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add support for ATmega168P.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix abbreviated name for ATmega324PA.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lech Perczak:
|
||||
bug #30946: Added support for ATmega8/16/32U2
|
||||
* avrdude.conf.in: Add ATmega8/16/32U2 entries.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David A Lyons:
|
||||
patch #7393: Adding ATtiny4313 Device to avrdude.conf.in
|
||||
* avrdude.conf.in: Add ATtiny4313 data.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: Bump timeout values to allow for slow clock
|
||||
speeds.
|
||||
* jtagmkII.c: (Ditto.)
|
||||
|
||||
2011-03-04 Eric B. Weddington <eric.weddington@atmel.com>
|
||||
|
||||
Thanks to Vitaly Chernookiy for the patch.
|
||||
* avrdude.conf.in: Add support for atmega324pa.
|
||||
* ChangeLog-2010: New file, rotate ChangeLog for new year.
|
||||
729
src/avrdude/ChangeLog-2012
Normal file
729
src/avrdude/ChangeLog-2012
Normal file
|
|
@ -0,0 +1,729 @@
|
|||
2012-12-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbdefs.h (USBDEV_BULK_EP_WRITE_STK600)
|
||||
(USBDEV_BULK_EP_READ_STK600): new define values
|
||||
* stk500v2.c (stk600_open): use the STK600 EP values,
|
||||
as they are different from AVRISPmkII
|
||||
|
||||
2012-12-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37942: Latest SVN can't program in dragon_jtag mode
|
||||
* jtagmkII.c (jtagmkII_initialize): For Xmega devices, and
|
||||
firmware >= 7.x, don't trigger a RESET, in order to work around a
|
||||
firmware bug that appears to be present in at least firmware 7.24
|
||||
for the Dragon.
|
||||
|
||||
2012-12-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Implement the "ocdrev" keyword
|
||||
* avrpart.c: (Dito)
|
||||
* avrpart.h: (Dito)
|
||||
* lexer.l: (Dito)
|
||||
* avrdude.conf.in: Add "ocdrev" key/value pairs, based
|
||||
on the AS6 XML file information.
|
||||
* jtag3.c: Use the ocdrev in the parameter block.
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Make jtag3_command() public
|
||||
* jtag3.h: (Dito.)
|
||||
* jtag3_private.h: Add two new commands
|
||||
* stk500v2.c: Implement the "MonCon disable" hack that
|
||||
allows temporarily falling back to ISP when trying to
|
||||
talk to a part that has debugWIRE enabled
|
||||
|
||||
2012-12-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* pickit2.c: reordered #includes for non-usb configuration
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Enable interactive adjustment of the various
|
||||
clock frequencies (JTAG Xmega, JTAG megaAVR, PDI Xmega)
|
||||
through the set_sck_period() callback.
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Remove unused code that was left over from
|
||||
cloning the jtagmkII.c implementation
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pgm_type.c: Add "jtagice3_isp" programmer hook
|
||||
* avrdude.conf.in: Add "jtag3isp" programmer
|
||||
* jtag3.c: jtag3_setparm() is now public
|
||||
* jtag3.h: (Dito)
|
||||
* stk500v2_private.h: Command 0x1D is CMD_SPI_MULTI only
|
||||
for STK500v2, AVRISPmkII, and JTAGICEmkII; for JTAGICE3,
|
||||
it's CMD_SET_SCK now; also add CMD_GET_SCK
|
||||
* avrpart.c (avr_get_output_index): New function
|
||||
* avrpart.h: (Dito)
|
||||
* stk500v2.c: Implement the pasthrough programmer glue logic
|
||||
for JTAGICE3 in ISP mode
|
||||
* stk500v2.h: (Dito)
|
||||
* avrdude.1: Document the JTAGICE3 support.
|
||||
|
||||
2012-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_read_byte, jtag3_write_byte): Remove the
|
||||
m->offset from addr, JTAGICE3 doesn't need it anymore (similar
|
||||
to JTAGICEmkII with 7+ firmware)
|
||||
* jtag3.c (jtag3_read_byte): Allow for full-page reads of
|
||||
EEPROM also for Xmega and debugWIRE, allow for signature
|
||||
read in debugWIRE
|
||||
|
||||
2012-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3_private.h: Add two more error detail codes I stumbled
|
||||
across during development
|
||||
* jtag3.c: (Dito.)
|
||||
* usb_libusb.c: Reduce timeouts from 100 to 10 s, still long
|
||||
enough, but not getting cold feet when something goes wrong.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Handle events returned by the ICE
|
||||
* usbdevs.h: Add defines that mark an event in return
|
||||
from usb_recv_frame().
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Remove "has_jtag" from Xmega A4 and D4
|
||||
devices, as they only have PDI.
|
||||
* jtag3.c (jtag3_page_erase): Actually implement this.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37265: wrong page sizes for XMega64xx in avrdude.conf
|
||||
* avrdude.conf.in: Fix page sizes for all Xmega devices,
|
||||
by cross-checking against Atmel Studio's device XML files
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Fill in the missing pieces for Xmega support (both,
|
||||
PDI and JTAG).
|
||||
* jtagmkII.c (jtagmkII_set_xmega_params): Use "fuse1" rather
|
||||
than "fuse0" memory space to fill in the NVM offset from, as
|
||||
there is no "fuse0" on some Xmega devices.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega256RFR2, ATmega128RFR2, ATmega64RFR2):
|
||||
New devices
|
||||
|
||||
2012-11-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First support for Atmel JTAGICE3. Guessed from USB sniffer
|
||||
traces made by Knut Schwichtenberg, and by similarity to
|
||||
JTAGICEmkII.
|
||||
Still quite incomplete, just megaAVR/JTAG is done by now.
|
||||
* jtag3.c: New file.
|
||||
* jtag3.h: (Dito.)
|
||||
* jtag3_private.h: (Dito.)
|
||||
* pgm_type.c: Add new programmers
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* usbdevs.h: Add new parameters
|
||||
* Makefile.am: Add new files
|
||||
* usb_libusb.c: Handle separate event endpoint, and larger
|
||||
(USB 2.0) packet sizes
|
||||
|
||||
2012-11-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Change all the USB details (endpoint numbers,
|
||||
max transfer size etc.) to a per-programmer adjustable value.
|
||||
* serial.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2012-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Replace outdated FSF postal address by a reference to
|
||||
the GPL info on their website.
|
||||
* jtagmkII.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
* linux_ppdev.h: (Dito.)
|
||||
* serbb.h: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* confwin.c: (Dito.)
|
||||
* buspirate.h: (Dito.)
|
||||
* avrftdi.h: (Dito.)
|
||||
* wiring.h: (Dito.)
|
||||
* jtagmkII.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* avrdude.1: (Dito.)
|
||||
* windows/Makefile.am: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* pickit2.h: (Dito.)
|
||||
* term.h: (Dito.)
|
||||
* tools/get-hv-params.xsl: (Dito.)
|
||||
* tools/get-stk600-cards.xsl: (Dito.)
|
||||
* tools/get-stk600-devices.xsl: (Dito.)
|
||||
* tools/get-dw-params.xsl: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* configure.ac: (Dito.)
|
||||
* doc/Makefile.am: (Dito.)
|
||||
* pgm_type.c: (Dito.)
|
||||
* butterfly.h: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* COPYING: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* jtagmkI.h: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* arduino.c: (Dito.)
|
||||
* arduino.h: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* freebsd_ppi.h: (Dito.)
|
||||
* avr910.h: (Dito.)
|
||||
* solaris_ecpp.h: (Dito.)
|
||||
* stk500.h: (Dito.)
|
||||
* jtagmkII_private.h: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* jtagmkI_private.h: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* stk500generic.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* avr.h: (Dito.)
|
||||
* ppi.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* lists.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* my_ddk_hidsdi.h: (Dito.)
|
||||
* tpi.h: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* stk500v2.h: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.h: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* Makefile.am: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2012-11-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #35186 inverting pins with "~" doesn't work for pin lists (i.e. vcc)
|
||||
bug #37727 Add support for LM3S811 dev board as a programmer
|
||||
* lexer.l,config_gram.y: accepting inverted pins at pin lists
|
||||
syntax: ~num or ~(num,num,...)
|
||||
* par.c: par_set_many_bits is now usable with inverted pins
|
||||
* avrftdi.c: fixed wrong index in ftdi_pin_name
|
||||
* avrdude.conf.in: added programmer lm3s811
|
||||
|
||||
2012-11-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* lexer.l,config_gram.y,config.[hc]: changed reading of numbers to integers
|
||||
except of default_bitclock which is the only real number.
|
||||
No signs are allowed as negative values do not make sense for current
|
||||
config values.
|
||||
* buspirate.c: include own header file buspirate.h
|
||||
* doc/.cvsignore: add programmers.texi to ignore list
|
||||
|
||||
2012-09-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/Makefile.am: add EXTRA_DIST, replace $(srcdir) by
|
||||
$(builddir) for generated files, so "make distcheck"
|
||||
works again
|
||||
|
||||
2012-09-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* doc/Makefile.am: add $(srcdir) to name of generated files, so BSD make
|
||||
find the files ( GNU make sees no difference if the
|
||||
file is called version.texi or ./version.texi )
|
||||
|
||||
2012-08-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7184 Support for PICKit2 programmer
|
||||
* Makefile.am: add pickit2 files
|
||||
* pickit2.[ch]: new programmer implementation
|
||||
* pgm_type.c: add pickit to list
|
||||
* avrdude.1: documentation for pickit2
|
||||
* doc/avrdude.texi: documentation for pickit2
|
||||
* avrdude.conf.in: add pickit2 programmer entry
|
||||
|
||||
2012-08-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support, see comment #30
|
||||
* ft245r.c: added semaphore workaround for MacOS X,
|
||||
added pthread_testcancel in reader thread
|
||||
|
||||
* configure.ac: added check for TYPE_232H in libftdi (not in libftdi < 0.20)
|
||||
* avrftdi.c: do not use TYPE_232H if not declared
|
||||
|
||||
2012-08-13 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi.c: fixes pin_limit for different FTDI devices (there was a mixup
|
||||
between 2232C and 2232H)
|
||||
|
||||
2012-07-29 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi.c: bugfixes (synchronisation) and maintenance (paged programming,
|
||||
nicer output, separation of parameter checking and actual code)
|
||||
|
||||
2012-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_memtype): return MTYPE_FLASH rather than
|
||||
MTYPE_SPM for non-Xmega flash regions
|
||||
|
||||
2012-07-20 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrpart.c, avrpart.h: adds avr_pin_name()
|
||||
|
||||
2012-07-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: check for libelf.h also in libelf/
|
||||
* fileio.c: include <libelf/libelf.h> if configure found this
|
||||
to be the case
|
||||
|
||||
2012-06-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: Check for presence of <pthread.h>
|
||||
* ft245r.c: Depend on HAVE_PTHREAD_H
|
||||
* Makefile.am: Add -lpthread if needed.
|
||||
|
||||
2012-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbtiny.c (usbtiny_paged_load, usbtiny_paged_write):
|
||||
fix breakage introduced by the recent page handling reorg;
|
||||
it used to cause an infinite loop
|
||||
|
||||
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Xmega page erase implementation for XPROG (AVRISPmkII, STK600)
|
||||
* stk500v2.c (stk600_xprog_page_erase): New function.
|
||||
|
||||
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Xmega page erase implementation for JTAGICEmkII
|
||||
* jtagmkII.c: Handle flash pages sizes > 256 bytes, implement
|
||||
page_erase() method
|
||||
* avrdude.conf.in: Change flash pagesize for all Xmega devices
|
||||
to 512 bytes
|
||||
* avr.c: Implement auto_erase, using page_erase if available
|
||||
* avr.h: Remove unused parameters from avr_read(), replace
|
||||
unused parameter in avr_write)() by auto_erase
|
||||
* stk500v2.c: Handle flash page sizes > 256 bytes
|
||||
* update.c (do_op): Handle new updateflags parameter
|
||||
* main.c: Implement auto_erase as page_erase if possible
|
||||
* update.h (enum updateflags): New enum
|
||||
* pgm.h (struct programmer_t): Add page_erase method
|
||||
|
||||
2012-04-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_paged_load, jtagmkII_paged_write): fix bug
|
||||
in memory type calculation for Xmega "boot" memory region.
|
||||
|
||||
2012-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* update.c (parse_op): do not assume default memtype here
|
||||
* main.c: after locating the part information, determine default
|
||||
memtype for all update options that didn't have a memtype
|
||||
specified; this is "application" for Xmega parts, and "flash" for
|
||||
everything else.
|
||||
|
||||
2012-04-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c: Rework the way ELF file sections are considered: while
|
||||
scanning the program header table, the offsets from a program
|
||||
header entry must never be used directly when checking the bounds
|
||||
of the current AVR memory region. Instead, they must always be
|
||||
checked based on the corresponding section's entry. That way,
|
||||
Xmega devices now properly take into account whether the segment
|
||||
fits into any of the application/apptable/boot memory region.
|
||||
|
||||
2012-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30756: When setting SUT to 64ms on XMEGA, avrdude doesn't
|
||||
read device signature
|
||||
* main.c: When reading the signature yields 0x000000 or 0xffffff,
|
||||
retry (up to twice) after some progressive delay.
|
||||
|
||||
2012-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATxmega16D4, ATxmega32D4, ATxmega64D4,
|
||||
ATxmega128D4): New devices. As Xmega D doesn't feature a fuse0
|
||||
memory cell, move that one out from the generic .xmega part into
|
||||
the individual Xmega A parts.
|
||||
|
||||
2012-04-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29019: pagel/bs2 warning when uploading using stk500 to xmega
|
||||
* stk500.c (stk500_initialize): Insert dummy values for PAGEL and
|
||||
BS2 if they are not present in the config file, in order to be able
|
||||
to proceed with the stk500_set_extended_parms() anyway.
|
||||
|
||||
2012-04-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h (struct pdata): add boot_start
|
||||
* stk500v2.c: For the "flash" pseudo-memory of Xmega devices,
|
||||
distinguish addresses between "application" and "boot" area.
|
||||
|
||||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf2b): When checking the bounds of the current
|
||||
program header segment, subtract `low' from ph[n].p_paddr in order
|
||||
to correct the magic section offsets for the AVR's non-flash
|
||||
memory regions.
|
||||
|
||||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf_get_scn): Rather than trying to just match whether
|
||||
any given section maps straight to a program header segment, use a
|
||||
more sophisticated decision that matches any section as long as it
|
||||
fits into the segment. This is needed for situations where the
|
||||
program header segment spans a larger area than the section data
|
||||
provided. (This can e.g. happen in an ELF file that contains no
|
||||
data at address 0, like a bootloader only.)
|
||||
|
||||
2012-04-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 2, fix for
|
||||
firmware >= V7.x)
|
||||
* jtagmkII.c: Add firmware-version dependent handling of Xmega parameters.
|
||||
V7.x firmware expects the NVM offsets being specified through the Xmega
|
||||
parameters command, but left out as part of the memory address itself.
|
||||
* jtagmkII_private.h: Add CMND_SET_XMEGA_PARAMS, and struct xmega_device_desc.
|
||||
* config_gram.y: Add mcu_base keyword.
|
||||
* avrpart.h: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in (.xmega): add mcu_base, and data memory segment.
|
||||
|
||||
2012-03-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 1, fix for
|
||||
firmware < V7.x)
|
||||
* jtagmkII.c: When going to write to the boot section of flash,
|
||||
use MTYPE_BOOT_FLASH rather than MTYPE_FLASH
|
||||
* jtagmkII_private.h: add MTYPE_BOOT_FLASH constant
|
||||
|
||||
2012-03-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII_private.h: Sort commands, response codes and events
|
||||
into numerical order.
|
||||
|
||||
2012-03-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30451: Accessing some Xmega memory sections gives not
|
||||
supported error
|
||||
* stk500v2.c: Handle all Xmega memory sections (except
|
||||
"prodsig" which is not documented in AVR079)
|
||||
* fileio.c: Treat the "boot", "application", and "apptable"
|
||||
regions (which are actually subregions of "flash") all as
|
||||
being flash, i.e. suppress trailing 0xFF bytes when reading
|
||||
them
|
||||
* avr.c: (Dito.)
|
||||
|
||||
2012-03-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_close): The GO command before signing off
|
||||
turned out to be not required for normal megaAVR devices, and to
|
||||
cause the exact opposite (i.e. the target stopping) on Xmega
|
||||
devices being programmed to JTAG. However, programming Xmega
|
||||
devcies through PDI *does* need the GO command.
|
||||
|
||||
2012-03-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Print a configuration summary at the end of the
|
||||
configure run
|
||||
|
||||
2012-02-11 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7718: Merge global data of avrftdi in a private data structure
|
||||
* avrftdi.[ch]: moved global data into private data structure, moved
|
||||
private defines from header file into source file
|
||||
|
||||
2012-02-06 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7720 Bug in EEPROM write
|
||||
* avrftdi.c: fixed wrong buffer address initialization in paged_write
|
||||
* fileio.c: added #include <stdint.h>
|
||||
|
||||
2012-02-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.c: cancel reader thread before exiting program
|
||||
|
||||
2012-02-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7717 avrftdi_flash_write is broken
|
||||
* avrftdi.c: fixed wrong buffer address initialization in paged_write
|
||||
bug #35296 Extraneous newlines in output.
|
||||
* main.c: fixed output of newlines at 100% progress
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7715 FT4232H support
|
||||
* avrdude.conf.in: added programmer 4232h
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the programmers lists)
|
||||
* doc/avrdude.texi: Add include of generated table of programmers
|
||||
* doc/Makefile.am: Add generating of table of programmers in programmers.texi
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34768 Proposition: Change the name of the AVR32 devices
|
||||
* avrdude.conf.in: renamed ucr2 to uc3a0512
|
||||
* avrpart.c: added cast to avoid compiler warning
|
||||
|
||||
2012-02-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (fileio_elf): Fix a copy'n-paste-o.
|
||||
|
||||
2012-02-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* par.c (par_desc): Move to end of file, outside the #if
|
||||
HAVE_PARPORT
|
||||
|
||||
2012-02-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Implement ELF file reading (finally). Requires libelf(3) to be
|
||||
present on the host system.
|
||||
* configure.ac (HAVE_LIBELF): Add logic to detect presence of
|
||||
libelf(3)
|
||||
* Makefile.am (avrdude_LDADD): Add @LIBELF@
|
||||
* fileio.h (FILEFMT): add FMT_ELF
|
||||
* fileio.c: Implement ELF file reader.
|
||||
* update.c (parse_op): add 'e' format specifier
|
||||
* avrdude.1: Document the ELF file reading capability
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2012-02-01 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.[ch]: new programmer type implementation
|
||||
* configure.ac: add pthread as link library
|
||||
* avrdude.conf.in: added some new programmers
|
||||
* Makefile.am: added new source files to compile
|
||||
* pindefs.h: change PIN_MASK, PIN_INVERSE to highest bit of unsigned int
|
||||
* pgm.[ch]: added generic function to print pin assignments (taken from par.c)
|
||||
* par.c: moved pin assigment print function to pgm.c
|
||||
|
||||
2012-02-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Sort keyword tokens into alphabetic order.
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y, lexer.l: removed unused ID/TKN_ID definitions
|
||||
* config.[hc]: removed unused function id(), use value.type to select
|
||||
values
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7437 modifications to Bus Pirate module
|
||||
patch #7686 Updating buspirate ascii mode to current firmware, use AUX
|
||||
as clock generator, and setting of serial receive timeout
|
||||
* buspirate.c: added paged_write, changed binary mode setup/detection,
|
||||
added clock output on AUX pin
|
||||
* avrdude.1: updated documentation
|
||||
* doc/avrdude.texi: updated documentation
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Parser does not need to know all programmer types now, new programmers
|
||||
will update only the table in pgm_type.c.
|
||||
* config_gram.y, lexer.l: removed programmer type keywords,
|
||||
use now locate_programmer_type() function
|
||||
* pgm_type.[ch]: added new files for table of programmer types
|
||||
* main.c: allow list of programmer types by -c ?type
|
||||
* avrdude.conf.in: changed all type keywords to quoted strings
|
||||
* doc/avrdude.texi: changed description of type definition, list
|
||||
of valid types is now included from generated file
|
||||
* doc/Makefile.am: generate list of programmer types for doc
|
||||
* all programmers [hc]: add xxx_desc string for description of programmer
|
||||
|
||||
2012-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: fixed detection of yylex_destroy availability
|
||||
by checking the version number of flex; bump required autoconf
|
||||
version to 2.60 (for AC_PROG_SED)
|
||||
|
||||
2012-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Replace the old, now-defunct #define YY_NO_UNPUT by
|
||||
the new %option nounput. This gets rid of a compiler warning.
|
||||
|
||||
2012-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add a connection_type attribute to each programmer, rather than
|
||||
trying to hard-code the default port name in main.c.
|
||||
* pgm.h: Add conntype to struct pgm.
|
||||
* lexer.l: Extend grammar for connection_type.
|
||||
* config_gram.y: (Dito.)
|
||||
* config.h: Add DEFAULT_USB, for symmetry with default_parallel
|
||||
and default_serial.
|
||||
* main.c: Replace old default portname hack by avrdude.conf-based
|
||||
knowledge.
|
||||
* usbtiny.c: Drop an old hack that's no longer necessary.
|
||||
* avrdude.conf.in: Add connection_type to each programmer
|
||||
definition.
|
||||
|
||||
2012-01-27 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: used parent parts for some other parts, added
|
||||
abstract .xmega part as parent for xmegas
|
||||
* main.c: hide parts starting with '.' from parts list
|
||||
|
||||
2012-01-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7688: Implement parent programmers feature
|
||||
* avrdude.conf.in: updated documentation comment and some programmers
|
||||
have now parents
|
||||
* config_gram.y: initpgm will now called at first use of programmer
|
||||
in main. parser sets only the function pointer in the pgm structure.
|
||||
Pin and pin lists definitions can now be empty to remove the parents
|
||||
setting.
|
||||
* doc/avrdude.texi: updated documentation
|
||||
* main.c: added call to pgm->initpgm after locate_programmer
|
||||
* pgm.[hc]: added field initpgm in structure, added function pgm_dup
|
||||
|
||||
2012-01-21 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #21797: AT90PWM316: New part description
|
||||
* avrdude.conf.in: added pwm316 with parent pwm3b but 16KB flash
|
||||
|
||||
2012-01-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Check for presence of lusb_usb.h as an alternative
|
||||
to usb.h; libusb-win32 switched to this name in version 1.2.5.0.
|
||||
* avrftdi.c: Decide whether to include <usb.h>, or <lusb0_usb.h>.
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2012-01-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avr.c: Unsigned variable was used for return code of paged_write/load
|
||||
functions. So a negative return code led never to a fallback to byte
|
||||
functions.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: if memory section is overwritten old entry is removed
|
||||
|
||||
(not in original patch)
|
||||
* config_gram.y: if programmer or part is defined twice, a warning is
|
||||
output and the first instance is removed
|
||||
|
||||
General cleanup and free functions, so valgrind does not report any lost
|
||||
blocks at program end.
|
||||
* avrpart.[hc]: added avr_free_(opcode|mem|part) functions
|
||||
* pgm.[hc]: added pgm_free function
|
||||
* update.[hc]: added free_update functions
|
||||
* config.[hc]: added cleanup_config function, use yylex_destroy to reset
|
||||
the lexer after usage. (So it can be reused.)
|
||||
* main.c: add cleanup_main function which is called by atexit() (This
|
||||
frees all lists so that at program exit only really lost memory is
|
||||
reported by valgrind.)
|
||||
* usbasp.c: added libusb_free_device_list() and libusb_exit() calls to
|
||||
avoid lost memory
|
||||
* buspirate.c: moved memory allocation from initpgm to setup and added
|
||||
free in teardown
|
||||
* configure.ac: add definition of HAVE_YYLEX_DESTROY if $LEX is flex.
|
||||
* Makefile.am: added . in front of SUBDIRS to build avrdude before trying
|
||||
to use it for creating the part list for the docs.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* usbasp.c: USB vid/pid/vendor/product from config file are used, for
|
||||
id "usbasp" nibobee and old usbasp are tried as they were currently
|
||||
implemented within usbasp
|
||||
* avrdude.conf.in: added usb params to "usbasp", added new entry "nibobee"
|
||||
with params which were hardcoded in usbasp.c, and added an entry
|
||||
"usbasb-clone" which only checks vid/pid.
|
||||
|
||||
2012-01-10 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #35261 avrftdi uses wrong interface in avrftdi_paged_(write|load)
|
||||
* avrftdi.c: Fixed interface and implementation of avrftdi_paged_(write|load)
|
||||
patch #7672 adding support for O-Link (FTDI based JTAG) as programmer
|
||||
* avrdude.conf.in: added o-link entry
|
||||
|
||||
2012-01-10 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7699 Read additional config files
|
||||
* main.c: Added reading of additional config files
|
||||
* avrdude.1: updated man page
|
||||
* doc/avrdude.texi: updated documentation
|
||||
|
||||
2012-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Bob Frazier:
|
||||
bug #35208: avrdude 5.11 on freebsd 8.2-STABLE does not reset
|
||||
Arduino Uno properly
|
||||
* arduino.c (arduino_open): Bump the timeout between pulling
|
||||
the DTR and RTS lines low and high.
|
||||
|
||||
2012-01-08 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Fixed following findings reported by cppcheck
|
||||
* avr910.c:625 (error) Possible null pointer dereference: cmd - otherwise it is redundant to check if cmd is null at line 624
|
||||
* avr910.c:626 (error) Possible null pointer dereference: cmd - otherwise it is redundant to check if cmd is null at line 624
|
||||
* avr910.c:168 (information) The scope of the variable 'devtype_1st' can be reduced
|
||||
* avr910.c:169 (information) The scope of the variable 'dev_supported' can be reduced
|
||||
* avrftdi.c:647 (error) Using sizeof for array given as function argument returns the size of pointer.
|
||||
* stk500v2.c:3347 (error) Memory leak: b
|
||||
* stk500v2.c:3452 (error) Memory leak: b
|
||||
* usbasp.c:554 (error) Using sizeof for array given as function argument returns the size of pointer.
|
||||
* usbasp.c:485 (information) The scope of the variable 'dly' can be reduced
|
||||
|
||||
2012-01-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Jason Kotzin:
|
||||
* usbasp.c (usbasp_spi_paged_load, usbasp_spi_paged_write):
|
||||
Fix buffer address calculation.
|
||||
|
||||
2012-01-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7629 add support for atmega48p
|
||||
* avrdude.conf.in: Added m48p with parent m48 + different signature
|
||||
|
||||
* avrdude.conf.in: made part parents (m88p = m88 + different signature,
|
||||
m168p = m168 + different signature)
|
||||
|
||||
2012-01-02 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #21663 AT90PWM efuse incorrect
|
||||
bug #30438 efuse bits written as 0 on at90pwmxx parts
|
||||
* avrdude.conf.in: (pwm2, pwm2b, pwm3, pwm3b) <efuse.write>: Write
|
||||
eight bits
|
||||
|
||||
* avrdude.conf.in: made part parents (pwm3 = pwm2, pwm3b = pwm2b,
|
||||
pwm2b = pwm2 + different signature)
|
||||
|
||||
* ChangeLog-2011: New file, rotate ChangeLog for new year.
|
||||
618
src/avrdude/ChangeLog-2013
Normal file
618
src/avrdude/ChangeLog-2013
Normal file
|
|
@ -0,0 +1,618 @@
|
|||
2013-12-15 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* pgm.c/pgm.h: fixed syntax error in const pointer to const
|
||||
|
||||
2013-12-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: bump version to 6.1-svn-20131205
|
||||
|
||||
2013-12-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40817: Elf file support (possibly) not working on 6.0.1 windows build
|
||||
* fileio.c (fileio): open file in binary mode also for FMT_ELF
|
||||
|
||||
2013-12-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Rework of bitbanging functions setpin, getpin, highpulsepin to make simplier use
|
||||
of new pindefs data in pgm structure
|
||||
* linuxgpio.c, bitbang.c, buspirate.c, par.c, pgm.h, term.c, serbb_*.c: changed
|
||||
interface of setpin, getpin, highpulsepin to take pin function as parameter
|
||||
(not the real number, which can be found by pgm->pinno[function])
|
||||
|
||||
2013-11-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #40748 linuxgpio doesn't work on Raspberry PI rev. 2.
|
||||
* linuxgpio.c: fixed check for unused pins to ignore the inverse flag
|
||||
* pindefs.c: fixed fill_old_pinlist to not create an empty mask with inverse flag set
|
||||
|
||||
2013-10-18 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* avrdude.conf.in (atmega1284): ATmega1284 variant added (same as ATmega1284p but with different signature)
|
||||
|
||||
2013-09-25 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
First part of patch #7720:
|
||||
* avrdude.conf.in: Add UM232H and C232H programmers
|
||||
|
||||
2013-09-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Daniel Rozsnyo:
|
||||
bug #40085: Typo fix in fuses report (for 6.1-svn-20130917)
|
||||
* main.c: Fix a typo.
|
||||
|
||||
2013-09-19 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
task #12798: Please cleanup #ifdef notyet entries in avrftdi.c
|
||||
* avrftdi.c: ditto.
|
||||
avrftdi.c: Remove DRYRUN-option.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40055: AVRDUDE segfaults when writing eeprom
|
||||
* main.c: Always clear the UF_AUTO_ERASE flag if either a
|
||||
non-Xmega device was found, or the programmer does not offer a
|
||||
page_erase method.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to post-6.0.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.0.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_initialize): Fix a buffer overflow by limiting
|
||||
the flash page cache size to at most "readsize". For Xmegas with
|
||||
a page size of 512 bytes, the maximum USB packet size was
|
||||
overflowed, and subsequently, a memmove copied beyond the end of
|
||||
the allocated buffer.
|
||||
* jtag3.c (jtag3_read_byte): Add the correct offset also for the
|
||||
various flash regions, so reading the apptable or boot regions
|
||||
yields the correct data.
|
||||
|
||||
2013-09-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Joakim Lubeck:
|
||||
bug #40040: Support for ATtiny20 and ATtiny40
|
||||
* avrdude.conf.in: Restructure the reduced-core tiny devices
|
||||
to use a common entry .reduced_core_tiny; add ATtiny20 and
|
||||
ATtiny40
|
||||
|
||||
2013-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Joakim Lubeck:
|
||||
bug #40033: Support for the XMegaE5 family
|
||||
* avrdude.conf.in (ATxmega8E5, ATxmega16E5, ATxmega32E5): New
|
||||
entries.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_set_sck_period): Revamp this to match the
|
||||
description/pseudo-code in appnote AVR068.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Stephen Roe:
|
||||
patch #7710: usb_libusb: Check VID/PID before opening device
|
||||
* usb_libusb.c (usbdev_open): Swap the sequence of verifying the
|
||||
VID:PID, and opening the device.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8176: butterfly.c (AVR109 protocol implementation) clean-up and bug-fixing
|
||||
* butterfly.c (butterfly_page_erase): Add dummy function to avoid
|
||||
segfault when writing to EEPROM.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #35474 Feature request: print fuse values in safemode output
|
||||
* config_gram.y: New configuration token "default_safemode".
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* config.h: Add variable default_safemode.
|
||||
* config.c: (Dito.)
|
||||
* main.c: Handle default_safemode, including -u option.
|
||||
* avrdude.1: Document all this.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by HubertB:
|
||||
patch #7657 Add ATmega406 support for avrdude using DRAGON + JTAG
|
||||
* avrdude.conf.in (ATmega406): New entry.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Marc de Hoop:
|
||||
patch #7606 ATtiny43u support
|
||||
* avrdude.conf.in (ATtiny43U): New entry.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #5708 avrdude should make 10 synchronization attempts instead of just one
|
||||
* stk500.c (stk500_getsync): Loop 10 times trying to get in
|
||||
sync with the programmer.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Ricardo Martins:
|
||||
bug #36384 ATxmega32A4 usersig size
|
||||
* avrdude.conf.in: Revamp all the ATxmega* entries. Add new
|
||||
entries for ATxmega128A1U, ATxmega128A3U, ATxmega128A4U,
|
||||
ATxmega128B1, ATxmega128B3, ATxmega128C3, ATxmega128D3,
|
||||
ATxmega16A4U, ATxmega16C4, ATxmega192A3U, ATxmega192C3,
|
||||
ATxmega192D3, ATxmega256A3BU, ATxmega256A3U, ATxmega256C3,
|
||||
ATxmega256D3, ATxmega32A4U, ATxmega32C4, ATxmega384C3,
|
||||
ATxmega384D3, ATxmega64A1U, ATxmega64A3U, ATxmega64A4U,
|
||||
ATxmega64B1, ATxmega64B3, ATxmega64C3, ATxmega64D3
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #35456 The progress bar for STK500V2 programmer is "wrong".
|
||||
* avr.c (avr_read, avr_write): Change the progress reporting for
|
||||
paged read/write from per-address to per-considered-page. This
|
||||
ought to give a realistic estimation about the time still to be
|
||||
spent.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34277: avrdude reads wrong byte order if using avr911 (aka butterfly)
|
||||
* butterfly.c (butterfly_read_byte_flash): Swap bytes received.
|
||||
|
||||
2013-09-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37768 Poll usbtiny 100 times at init time to handle low-clock devices
|
||||
* doc/avrdude.texi: Add a FAQ entry about how to connect to a
|
||||
target where the firmware has reduced the internal clock speed.
|
||||
|
||||
2013-09-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28344 chip_erase_delay too short for ATmega324P, 644, 644P, and 1284P
|
||||
* avrdude.conf: Bump the chip_erase_delay for all ATmega*4 devices
|
||||
to 55 ms. While the datasheet still claims 9 ms, all the XML files
|
||||
tell either 45 or 55 ms, depending on STK600 or not.
|
||||
|
||||
2013-09-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (fileio): Don't exit(1) if something goes wrong; return
|
||||
-1 instead. Don't refer to obsolete option -f to specify the file
|
||||
format.
|
||||
|
||||
2013-09-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Matthias Trute:
|
||||
bug #36901 flashing Atmega32U4 EEPROM produces garbage on chip
|
||||
* avrdude.conf.in (ATmega32U4): Fix EEPROM pagesize to 4, the
|
||||
datasheet is wrong here.
|
||||
|
||||
2013-09-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: check for ar and ranlib in the target tool
|
||||
namespace, rather than on the host.
|
||||
|
||||
2013-09-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix byte-wise EEPROM and flash writes on Xmega
|
||||
* jtagmkII_private.h (MTYPE_EEPROM_XMEGA): New memory type.
|
||||
* jtagmkII.c (jtagmkII_write_byte): For Xmega EEPROM, use
|
||||
memory type MTYPE_EEPROM_XMEGA; for flash writes, always
|
||||
write 2 bytes starting on an even address.
|
||||
|
||||
2013-09-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* term.c: Implement the "verbose" terminal mode command.
|
||||
* avrdude.1: Document this.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-09-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_write_byte): Do not attempt to start the paged
|
||||
algorithm for EEPROM when being connected through debugWIRE.
|
||||
|
||||
2013-09-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Extend the single-byte algorithm to all devices, both flash and
|
||||
EEPROM. (Flash cells must have been erased before though.)
|
||||
* jtag3.c (jtag3_initialize): OCDEN no longer needs to be
|
||||
considered; a session with "programming" purpose is sufficient
|
||||
* jtag3.c (jtag3_write_byte): Use the paged algorithm for all
|
||||
flash and EEPROM areas, not just Xmega.
|
||||
|
||||
2013-09-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix single-byte EEPROM updates on Xmega:
|
||||
* jtag3_private.h (MTYPE_EEPROM_XMEGA): New define.
|
||||
* jtag3.c (jtag3_write_byte): When updating flash or
|
||||
EEPROM on Xmega devices, resort to jtag3_paged_write()
|
||||
after filling and modifying the page cache.
|
||||
* jtag3.c (jtag3_paged_write): use MTYPE_EEPROM_XMEGA
|
||||
where appropriate.
|
||||
* jtag3.c (jtag3_initialize): Open with debugging intent
|
||||
for Xmega devices, so single-byte EEPROM updates will
|
||||
work.
|
||||
|
||||
2013-09-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Matthias Neeracher:
|
||||
bug #38732: Support for ATtiny1634
|
||||
* avrdude.conf.in (ATtiny1634): New entry.
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Brane Ždralo:
|
||||
patch #7769: Write flash fails for AVR910 programmers
|
||||
* avr910.c (avr910_paged_write): Fix flash addresses in
|
||||
'A' command.
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Fred (magister):
|
||||
bug #38951: AVR109 use byte offset instead of word offset
|
||||
patch #8045: AVR109 butterfly failing
|
||||
* butterfly.c (butterfly_paged_load, butterfly_paged_write):
|
||||
fix calculation of 'A' address when operating on flash memory.
|
||||
It must be given in terms of 16-bit words rather than bytes.
|
||||
|
||||
2013-09-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrftdi.c, avrftdi_private.h: added tx buffer size, and use
|
||||
smaller block sizes as larger sometimes hang
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.h: Remove the erase cycle counter (options -y / -Y).
|
||||
* avr.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* avrdude.1: Undocument -y / -Y.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39691 Buffer overrun when reading EEPROM byte with JTAGICE3
|
||||
* jtag3.c (jtag3_initialize): initialize the eeprom_pagesize
|
||||
private attribute so the page cache will actually be usable
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #38580 Current svn head, xmega and fuses, all fuses tied to fuse0
|
||||
* jtag3.c (jtag3_read_byte, jtag3_write_byte): Correctly apply the
|
||||
relevant part of mem->offset as the address to operate on.
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c: Fix "unused variable" warnings.
|
||||
* avr.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Travis Griggs:
|
||||
bug #38307: Can't write usersig of an xmega256a3
|
||||
* stk500v2.c (stk600_xprog_page_erase): allow erasing the usersig space.
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Robert Niemi:
|
||||
bug #35800: Compilation error on certain systems if parport is disabled
|
||||
* linux_ppdev.h: Conditionalize inclusion of <linux/parport.h> and
|
||||
<linux/ppdev.h> on HAVE_PARPORT
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
* pickit.c (usb_open_device): Use %p rather than %X to print "handle"
|
||||
which is a pointer
|
||||
* jtag3.c (jtag3_initialize): Initialize "flashsize" to be sure it
|
||||
proceeds with a valid value.
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
* buspirate.c: Turn the "cmd" argument of the various methods into
|
||||
a "const unsigned char *"; while doing this, declare all arrays being
|
||||
passed as arguments to be pointers rather than arrays, as the latter
|
||||
obfuscates the way arrays are being passed to a callee in C.
|
||||
* avrftdi.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* avrftdi_tpi.c: (Dito.)
|
||||
* avrftdi_tpi.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #38023: avrdude doesn't return an error code when attempting
|
||||
to upload an invalid Intel HEX file
|
||||
* fileio.c (ihex2b): Turn the "No end of file record found" warning
|
||||
into an error if no valid record was found at all.
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Claus-Justus Heine:
|
||||
bug #38713: Compilation of the documentation breaks with texinfo-5
|
||||
* doc/avrdude.texi: Turn @itemx into @item, add @headitem to STK600
|
||||
Routing/Socket card table
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add trace output for -vvv to non-TPI functions, too.
|
||||
|
||||
2013-09-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c (usbasp_tpi_paged_load): Calculate correct
|
||||
buffer address.
|
||||
* usbasp.c (usbasp_tpi_paged_write): Calculate correct
|
||||
buffer address; don't issue a SECTION_ERASE command for
|
||||
each page (a CHIP_ERASE has been done before anyway);
|
||||
remove the code that attempted to handle partial page
|
||||
writes, as all writes are now done with a full page.
|
||||
|
||||
2013-09-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add more trace output, by now only for the TPI
|
||||
functions.
|
||||
|
||||
2013-08-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c (usbasp_transmit): Add -vvvv trace output.
|
||||
|
||||
2013-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39893: Verification failure with AVRISPmkII and Xmega
|
||||
* stk500v2.c (stk600_xprog_page_erase): Fix argument that is
|
||||
passed to stk600_xprog_memtype()
|
||||
|
||||
2013-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf2b): replace elf_getshstrndx() by
|
||||
elf_getshdrstrndx() as the former one is deprecated
|
||||
|
||||
2013-06-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
use bitbanging on ftdi mpsse when wrong pins are used
|
||||
* avrftdi.c, avrftdi_private.h: added additional pin check
|
||||
and bitbanging fallback
|
||||
* pindefs.[ch]: added a flag to enable/disable output
|
||||
* ft245r.c: changes because of added flag above
|
||||
|
||||
2013-05-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by "Malte" and John McCorquodale:
|
||||
patch #7876 JTAGICE mkII fails to connect to attiny if debugwire
|
||||
is enabled AND target has a very slow clock
|
||||
* jtagmkII.c (jtagmkII_getsync): When leaving debugWIRE mode
|
||||
temporarily, immediately retry with ISP, rather than leaving.
|
||||
* stk500v2 (stk500v2_program_enable): Implemented similar logic
|
||||
for the JTAGICE3.
|
||||
|
||||
2013-05-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: reactivate check for TYPE_232H, which does not
|
||||
exist in libftdi < 0.20
|
||||
* avrftdi*.*: changed include check for libftdi/libusb, deactivate
|
||||
232H if not available
|
||||
* ft245r.c: changed include check for libftdi/libusb
|
||||
|
||||
2013-05-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c (main): Add option -l logfile.
|
||||
* avrdude.1: Document -l option.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-05-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: if both found libftdi and libftdi1 use only libftdi1
|
||||
* avrdude.conf.in: fixed buff pins of avrftdi programmers (low
|
||||
active buffer need now inverted numbers)
|
||||
* avrftdi*.*: accept also old libftdi (0.20 still works with it),
|
||||
added powerup to initialize
|
||||
* ft245r.c: accept libftdi1, code cleanup and make it more similar
|
||||
to avrfdti (os they might be merged someday)
|
||||
|
||||
2013-05-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.0rc1.
|
||||
|
||||
2013-05-07 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_private.h: Change size of pin_checklist to N_PINS (from N_PINS-1)
|
||||
* avrftdi.c: Adapt code to new size of pin_checklist. Remove pins_check()
|
||||
from set_pin().
|
||||
Add pgm->power[up|down] functions as well as fill pgm->enable|disable with
|
||||
proper content as suggested by Rene Liebscher.
|
||||
|
||||
2013-05-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* pindefs.h: use unsigned int if stdint.h is not available and UINT_MAX is 0xffffffff
|
||||
otherwise use unsinged long
|
||||
* ft245r.c: added support for more pin functions led, vcc, buff
|
||||
|
||||
2013-05-06 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_tpi.c: instead of private set_pin() function pointer use the one
|
||||
declared in struct PROGRAMMER.
|
||||
* avrftdi_private.h: remove set_pin function pointer. Add pin_checklist_t
|
||||
member to check pgm->setpin calls during runtime.
|
||||
* avrftdi.c: remove set_pin function pointer init, add pgm->setpin init.
|
||||
Convert avrftdi to new 0-based pindefs infrastructure.
|
||||
* avrdude.conf.in: Change all avrftdi-based programmers' pin definitions to
|
||||
0-based.
|
||||
|
||||
2013-05-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pindefs.h: Include "ac_cfg.h" before testing for HAVE_* macros.
|
||||
|
||||
2013-05-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* main.c: revert to rev 1159 (doing pgm_display after pgm_open)
|
||||
* avrpart.[ch]: moved avr_pin_name to pindefs.[ch]
|
||||
* pgm.c: moved pins_to_str to pindefs.[ch], added initialization of
|
||||
new pin definitions in pgm_new()
|
||||
* pindefs.[ch]: added moved functions from other files, added a lot of
|
||||
documentation, reformatted files using astyle to have consistent spacing,
|
||||
added a new generic check function for pins
|
||||
* ft245r.c: used new generic pin check function
|
||||
|
||||
2013-05-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Create new pin definition data structures to support 0-based pin numbers,
|
||||
and mixed inverse/non-inverse pin lists.
|
||||
* avrftdi.c,buspirate.c,linuxgpio.c,par.c,serbb_*.c: added function call
|
||||
to fill old pinno entries from new pin definitions.
|
||||
* pindefs.[hc]: added data struct and helper functions for new pin definitions
|
||||
* avrdude.conf.in: pins in entries using ftdi_syncbb are now 0-based
|
||||
* config_gram.y: allow combinations of inverted and non-inverted pins in pin lists
|
||||
* ft245r.c: reworked to work directly with the new pin definitions,
|
||||
pins are now 0-based, inverse pins are supported, buff is supported
|
||||
* pgm.[ch]: added new pin definitions field to programmer structure,
|
||||
adapted pin display functions
|
||||
|
||||
2013-05-03 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_private.h: Remove update forward declaration from avrftdi_print to
|
||||
avrftdi_log.
|
||||
* avrftdi_tpi.c: Do all I/O in terms of pgm->cmd_tpi()-calls instead of
|
||||
avrftdi_tpi_[read,write]_byte().
|
||||
Remove unnecessary set_pin call to set MOSI high, speeds up I/O.
|
||||
Removes SKEY array, moves it to tpi.h.
|
||||
Integrate new avr_tpi_[program_enable,chip_erase]() and functions into
|
||||
avrftdi_tpi.
|
||||
* avrftdi_tpi.h: Remove avrftdi_tpi_[program_enable,chip_erase] forward
|
||||
declarations.
|
||||
* avr.c: Adds avr_tpi_chip_erase() generic TPI chip erase function.
|
||||
Adds avr_tpi_program_enable() - generic TPI external programming enable
|
||||
function. Sets guard time, reads identification register, sends SKEY command
|
||||
and key, checks NVMEN bit. The required guard time has to be passed as
|
||||
parameter.
|
||||
* tpi.h: Adds SKEY array including CMD_SKEY in "correct" order.
|
||||
|
||||
2013-05-02 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_private.h: Add libusb-1.0 include to fix include order in windows.
|
||||
* NEWS: Add notice avrftdi supporting TPI
|
||||
* avr.c: Fix avr_tpi_poll_nvmbsy() - poll read data instead of return code
|
||||
* avrftdi_private.h, avrftdi.c: move logging #defines to from avrftdi.c to
|
||||
avrftdi_private.h, so that they are available for avrftdi_tpi, too.
|
||||
|
||||
2013-04-30 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* tpi.h: Add definition for TPI Identification Code
|
||||
* avrftdi_tpi.c: Add TPI-support for FTDI-based programmers
|
||||
* avrftdi_private.h: Add common include file for FTDI-based programmers
|
||||
|
||||
2013-04-28 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdic: Rework of textual output. Messages are divided by severity and
|
||||
printed accordingly to the verbosity, as specified by the user. The provided
|
||||
severity level are (ERROR, WARN, INFO, DEBUG, TRACE). Where "ERROR" messages
|
||||
are always printed. Shortcut-macros including function, from which the
|
||||
output was generated, and line number were also added.
|
||||
Some log messages were updated and other code warnings removed.
|
||||
|
||||
2013-04-27 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* configure.ac: Add libftdi1 library check, remove TYPE_232H DECL check
|
||||
* Makefile.am: Add @LIBFTDI1@ to avrdude_LDADD
|
||||
* avrftdi.c: Update from libftdi0 to libftdi1. Use libftdi1's function to
|
||||
find a device by vid/pid/serial instead of doing it ourself and add/update
|
||||
error messages. avrftdi_print is changed so that a message is printed when
|
||||
the verbosity level is greater or equal the message level, to have always-on
|
||||
messages.
|
||||
Fix a bug where the RX fifo of the FTDI chip is full, resulting in STALL/NAK
|
||||
of the ongoing OUT request and subsequently timeout, because an IN request
|
||||
cannot be issued due to the synchronous part of libftdi. This should fix
|
||||
#38831 and #38659.
|
||||
|
||||
2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER
|
||||
by this; automake 1.13+ barfs.
|
||||
|
||||
2013-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega2564RFR2, ATmega1284RFR2, ATmega644RFR2):
|
||||
New devices
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7724 Add TPI support for Bus Pirate using bitbang mode
|
||||
* buspirate.[ch]: added support for BusPirate Bitbanging
|
||||
* pgm_type.c: added entry for buspirate_bb
|
||||
* avrdude.conf.in: added entry for buspirate_bb
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7936 Patch to support BusPirate AVR Extended Commands mode
|
||||
* buspirate.c: added support for BusPirate AVR Extended Commands mode
|
||||
* avrdude.1: added doc for nopagedread parameter
|
||||
* doc/avrdude.texi: added doc for nopagedread parameter
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7723 Bus Pirate “raw-wire” mode which can run down to 5 kHz
|
||||
* buspirate.c: added raw wire mode
|
||||
* avrdude.1: added doc for rawfreq parameter
|
||||
* doc/avrdude.texi: added doc for rawfreq parameter
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #37977 Support for Openmoko Debug Board
|
||||
* avrdude.conf.in: added openmoko entry
|
||||
|
||||
2013-01-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7932 Read USBtiny VID and PID from avrdude.conf if provided.
|
||||
* avrdude.conf.in: added usbpid, usbvid to usbtiny
|
||||
* usbtiny.[ch]: use usbpid, usbpid if provided in config file
|
||||
|
||||
2013-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #38172: avrftdi: Incorrect information in avrdude.conf
|
||||
* avrdude.conf.in (avrftdi): fix comments about ACBUS vs. ADBUS;
|
||||
add a comment that the MPSSE signals are fixed by the FTDI
|
||||
hardware and cannot be changed
|
||||
|
||||
2013-01-09 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7165 Add support for bitbanging GPIO lines using the Linux sysf GPIO interface
|
||||
* doc/avrdude.texi,avrdude.1: added doc for linuxgpio
|
||||
* avrdude.conf.in: added template for linuxgpio programmer
|
||||
* config_gram.y: pin numbers restricted to [PIN_MIN, PIN_MAX]
|
||||
* pindefs.h: added PIN_MIN, PIN_MAX, removed unused LED_ON/OFF
|
||||
* configure.ac: configure option enable-linuxgpio, print of enabled options
|
||||
* linuxgpio.[ch]: new source for linuxgpio programmer
|
||||
* Makefile.am: added linuxgpio to sources list
|
||||
* pgm_type.c: added linuxgpio to programmer types list
|
||||
|
||||
2013-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkI.c (jtagmkI_prmsg): replace a putchar() by putc(...stderr)
|
||||
* jtagmkII.c (jtagmkII_prmsg): (Dito.)
|
||||
* jtag3.c (jtag3_prevent, jtag3_prmsg): (Dito.)
|
||||
|
||||
2013-01-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_open): Downgrade the max transfer size for
|
||||
the main data endpoints when being forced so by the USB; this can
|
||||
happen when attaching the JTAGICE3 to a USB 1.1 connection
|
||||
* jtag3.c (jtag3_initialize): When detecting a downgraded max
|
||||
transfer size on the JTAGICE3 (presumably, due to being connected
|
||||
to USB 1.1 only), bail out as its firmware cannot properly handle
|
||||
this (by now)
|
||||
|
||||
2013-01-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ChangeLog: annual ChangeLog rotation time
|
||||
697
src/avrdude/ChangeLog-2014
Normal file
697
src/avrdude/ChangeLog-2014
Normal file
|
|
@ -0,0 +1,697 @@
|
|||
2014-11-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ser_win32.c (net_send): Properly declare argument 2 as being a
|
||||
pointer to const data.
|
||||
|
||||
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
* ser_posix.c: Add a hack to allow for arbitrary baud rates on
|
||||
Linux
|
||||
|
||||
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
* configure.ac: Check for ws2_32 library
|
||||
* ser_win32.c: Add hooks for forwarding serial data over
|
||||
TCP connections
|
||||
* avrdude.1: Drop previous restriction of -P net:
|
||||
* doc/avrdude.conf: (Dito.)
|
||||
|
||||
2014-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #42908: no external reset at JTAGICE3
|
||||
* jtag3.c (jtag3_initialize): Retry with external reset applied if
|
||||
the first sign-on attempt fails.
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Allow the -B option argument to be suffixed with Hz,
|
||||
kHz, or MHz, in order to specify a bitclock frequency rather than
|
||||
period.
|
||||
* avrdude.1: Document the -B option changes.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
* avrdude.conf.in (ATtiny25, ATtiny45, ATtiny85): Fix size of
|
||||
"calibration" memory area
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43137: Writing and reading incorrect pages when using jtagicemkI
|
||||
* jtagmkI.c (jtagmkI_paged_write, jtagmkI_paged_load): correctly
|
||||
calculate the size of a partial (non-pagesize) buffer
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43078: AVRDUDE crashes after sucessfully reading/writing eeprom
|
||||
* jtag3.c (jtag3_edbg_recv_frame): Return correct length as
|
||||
reported in the response packet, rather than full 512 byte which
|
||||
are always reported by the CMSIS-DAP layer. Miscalculations
|
||||
based on the wrongly reported length caused heap corruption
|
||||
elsewhere, so this is presumably also a fix for bug #43078.
|
||||
|
||||
2014-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #41561: AVRDUDE 6.0.1/USBasp doesn't write first bytes of
|
||||
flash page
|
||||
* usbasp.c (usbasp_spi_paged_write): Remove USBASP_BLOCKFLAG_LAST.
|
||||
It is no longer needed, as we always write full pages now in paged
|
||||
write mode.
|
||||
|
||||
2014-11-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43626: Inconsistent timeouts in stk500v2
|
||||
* stk500v2.c (stk500v2_recv): Add a reference to the bug report
|
||||
but don't change anything, lest to break it somehow
|
||||
|
||||
2014-11-14 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8529 2 more ftdi_syncbb devices
|
||||
* avrdude.conf.in: added 2 new programmers
|
||||
|
||||
2014-11-14 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #40142 Floating point exception on Ubuntu 10.04
|
||||
* avr.c: avoid division by zero in report_progress(), eg. when
|
||||
writing an empty eeprom file were total becomes 0
|
||||
|
||||
2014-11-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8504 buspirate: Also support "cpufreq" extended parameter
|
||||
in binary mode
|
||||
* buspirate.c: applied patch + switch off at disable (even when
|
||||
a reset follows) + some general whitespace/tab cleanup
|
||||
|
||||
2014-10-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37441: lockbits in ATxmega + avrdude = problem
|
||||
* fileio.c: replace strmcp(..., "lock") by strncmp(..., "lock", 4)
|
||||
where applicable
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
|
||||
2014-10-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #42267: jtag3isp fails to read lock and fuse bytes directly
|
||||
after changing lock byte
|
||||
* stk500v2.c (stk500isp_write_byte): As a workaround for broken
|
||||
tool firmware, add 10 ms of delay before returning from any
|
||||
single-byte write operation.
|
||||
|
||||
2014-10-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Use stk500isp_read_byte/stk500isp_write_byte for
|
||||
every byte-wide access (rather than JTAGICE3 only). This finally
|
||||
obsoletes the use of the prehistoric SPI_MULTI command where
|
||||
AVRDUDE used to assemble all the low-level ISP stuff by itself.
|
||||
|
||||
2014-10-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22248: Read efuse error
|
||||
* avrdude.conf.in (m168, m328, m48, m88, t1634, t26, t261, t461,
|
||||
t861, t88): In efuse (or hfuse for t26) read operation, turn all
|
||||
bits in byte 3 from "x" to "o" (output); this is a first step
|
||||
towards fixing the symptoms mentioned in the bug, by unifying the
|
||||
behaviour between different AVRs. Not touched are the historic
|
||||
devices where the fuses are not documented to form a full byte
|
||||
each (2333, 4433, 4434, 8535, m103, m161, m163).
|
||||
|
||||
2014-09-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43268: usb_drain() call causes LUFA AVR-ISP MKII Code to Fail
|
||||
* usb_libusb.c (usbdev_drain): Make this a dummy function only.
|
||||
|
||||
2014-08-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7694 Add support for the atmega32m1
|
||||
* avrdude.conf.in: added ATmega32M1
|
||||
|
||||
2014-08-18 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8440 Print part id after signature
|
||||
When printing the part signature also print the part id.
|
||||
* avrpart.c (locate_part_by_signature): New function.
|
||||
* libavrdude.h (locate_part_by_signature): New function.
|
||||
* main.c (main): Use the new function to find the part and print its id.
|
||||
|
||||
2014-08-18 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8511 Fix reset on FT245R
|
||||
* ft245r.c: applied patch
|
||||
|
||||
2014-08-18 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #43002 usbasp debug output typo
|
||||
* usbasp.c: fixed typos
|
||||
|
||||
2014-07-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #42662 clang warnings under FreeBSD 10.x
|
||||
* avrftdi.h: Fix header guard macro name.
|
||||
* pgm_type.c (programmers_types): Remove duplicate "const".
|
||||
|
||||
2014-07-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42662 clang warnings under FreeBSD 10.x
|
||||
* avrftdi.c: remove warnings
|
||||
* buspirate.c: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* libavrdude.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
|
||||
* config_gram.y: fix problem when using parent part with usbpid lists
|
||||
(existing list was extended not overwritten)
|
||||
|
||||
2014-07-11 Axel Wachtler <axel@uracoli.de>
|
||||
|
||||
* avrftdi.c: rollback to vfprintf, fixed error from -r1305, (patch #8463)
|
||||
|
||||
2014-06-23 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* linux_ppdev.h: added missing msg level for avrdude_message
|
||||
in ppi_claim/ppi_release macros
|
||||
* avrftdi.c: added break at end of default
|
||||
|
||||
2014-06-21 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8419 fix ftdi_syncbb hang with libftdi 1
|
||||
* ft245r.c: set pthread cancel type to asynchronous, reorder ftdi_usb_close/deinit
|
||||
|
||||
2014-06-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrftdi_private.h: added missing msg level for avrdude_message
|
||||
in E/E_VOID macros
|
||||
|
||||
2014-06-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Removing exit calls from config parser
|
||||
* config.h: cleanup, left only internally needed definitions
|
||||
* config.c: removed exit calls, use yyerror and yywarning
|
||||
* config_gram.y: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* libavrdude.h: removed internal definitions of config parser
|
||||
* main.c: removed yyerror, it is now in config.c
|
||||
* jtagmkII.c: added missing free in error case
|
||||
* pgm.c: replaced exits by returns
|
||||
* pickit2.c: add missing return
|
||||
|
||||
2014-06-13 Axel Wachtler <axel@uracoli.de>
|
||||
|
||||
start removing global "verbose" variable, for avrdude library.
|
||||
* arduino.c: added verbose level in avrdude_message()
|
||||
* avr910.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* flip1.c: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* libavrdude.h: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-06-11 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42516 spelling-error-in-binary
|
||||
* stk500v2.c, avrftdi.c, usbasp.c: fixed spelling errors
|
||||
|
||||
2014-06-01 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42337 avrdude.conf updates for UM232H/CM232H
|
||||
* avrdude.conf.in: fixed entries as proposed
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #41854: avrdude 6.1 does not compile on systems without libUSB
|
||||
Submitted by Didrik Madheden:
|
||||
* flip1.c: Provide dummy functions for the #ifndef HAVE_LIBUSB case
|
||||
* flip2.c: (Dito.)
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* libavrdude.h: Join the former "public" header files (avr.h avrpart.h pindefs.h
|
||||
serial.h fileio.h safemode.h update.h pgm_type.h config.h confwin.h lists.h) into
|
||||
a single header that can be included by anyone wanting to link against the
|
||||
library
|
||||
* avr.h: Remove file.
|
||||
* avrpart.h: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* Makefile.am: Adapt for new include file constellation; install shared lib
|
||||
* configure.ac: Bump version date
|
||||
* arduino.c: #include <libavrdude.h> rather than a bunch of different headers
|
||||
* avr910.c: (Dito.)
|
||||
* avr910.h: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* avrftdi_private.h: (Dito.)
|
||||
* avrftdi_tpi.c: (Dito.)
|
||||
* avrftdi_tpi.h: (Dito.)
|
||||
* avr.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* confwin.c: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* flip1.c: (Dito.)
|
||||
* flip1.h: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* flip2.h: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* ft245r.h: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* libavrdude.h: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* lists.c: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pgm_type.c: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pickit2.h: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* stk500v2_private.h: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* term.h: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Cleanup unused include files.
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* linux_ppdev.h: Caught two more instances of exit()
|
||||
* configure.ac: Add AC_CONFIG_MACRO_DIR as suggested by libtoolize
|
||||
* Makefile.am: add -I m4 to ACLOCAL_AMFLAGS as suggested by libtoolize
|
||||
|
||||
2014-05-16 Axel Wachtler <axel@uracoli.de>
|
||||
|
||||
* arduino.c: Replacing all occurences of fprintf(stderr,...) with avrdude_message(...)
|
||||
in potential library functions.
|
||||
* avr910.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* avrftdi_private.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* flip1.c: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* linux_ppdev.h: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-05-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version, add libtool hooks
|
||||
* Makefile.am: First attempt to define building a shared library
|
||||
(not to be installed by now)
|
||||
|
||||
2014-05-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* dfu.c (dfu_open, dfu_init): Fix signature of the dummy functions
|
||||
(in the !HAVE_LIBUSB case) to match prototypes.
|
||||
|
||||
2014-05-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Replace all occurences of exit() in potential library
|
||||
functions by appropriate return values
|
||||
* avrftdi.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
|
||||
2014-05-07 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42310: New part description for AT90PWM216
|
||||
* avrdude.conf.in: added pwm216 entry
|
||||
|
||||
2014-05-07 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42158: Linux GPIO - Source Typo
|
||||
* pindefs.h: fixed typo
|
||||
|
||||
2014-04-14 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42056: double free or corruption triggered at exit
|
||||
* pgm.c: copy usbpid list in pgm_dup
|
||||
|
||||
2014-04-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Remove the note that users might edit the system-wide
|
||||
config file. This file will be overwritten by the next
|
||||
installation, so it's not a good idea to manually modify it.
|
||||
Using the -C +file option is a much better way for user
|
||||
modifications.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
* avrdude.conf.in: Add a warning to not modify the file manually.
|
||||
|
||||
2014-03-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-6.1.
|
||||
|
||||
2014-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.1.
|
||||
|
||||
2014-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pgm.c (pgm_free): Cleanup police: destroy the p->usbpid
|
||||
list when freeing the programmer struct.
|
||||
|
||||
2014-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40782: Verify errors for object size > 16 k on x32e5 due
|
||||
to typo in avrdude.conf
|
||||
* avrdude.conf.in (ATmega8E5, ATmega32E5): fix boot location
|
||||
|
||||
2014-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (atmelice, atmelice_pdi, atmelice_dw, atmelice_isp):
|
||||
New entries.
|
||||
* avrdude.1: Document the Atmel-ICE addition.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
* usbdevs.c (USB_DEVICE_ATMEL_ICE): New entry.
|
||||
|
||||
2014-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Bump copyright year.
|
||||
|
||||
2014-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_recv): avoid memmov'ing more data than available
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Documentation update for EDBG.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: For EDBG protocol, always use 512-byte block I/O. The
|
||||
lower layers will split this according to the EP's maxsize. This
|
||||
makes it work over USB 1.1 connections (albeit very slowly, due to
|
||||
the interrupt transfers used).
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Turn the usbpid parameter of the programmer into
|
||||
a list of PIDs. Make the JTAGICE3 programmer handle a list of
|
||||
PIDs, by trying each of them in sequence. Use a single, central
|
||||
jtag3_open_common() function to handle the common code of all
|
||||
jtag3_open_* functions. Centralize all USB VID/PID definitions in
|
||||
usbdevs.h.
|
||||
* flip1.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtag3.h: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_open): Replace all calls to exit(1) by
|
||||
return -1
|
||||
|
||||
2014-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3_private.h: Add EDBG/CMSIS-DAP specific constants.
|
||||
* jtag3.c: Add EDBG/CMSIS-DAP protocol implementation.
|
||||
* serial.h: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* configure.ac: (Dito.)
|
||||
* avrdude.conf.in: Add JTAGICE3 and XplainedPro entries using
|
||||
EDBG.
|
||||
* configure.ac: Bump version date.
|
||||
|
||||
2014-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_recv_frame): Fix a bug where a new recv
|
||||
request was issued even though all desired data had aldready
|
||||
been received.
|
||||
|
||||
2014-02-21 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* serial.h: Change the second parameter of the ser_open method
|
||||
from "baud" into a "union pinfo", so the USB parameters can be
|
||||
passed without hacks.
|
||||
* arduino.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
[bug #41402] dfu.c missing include <stdint.h>
|
||||
* dfu.c: include <stdint.h> where uint16_t is defined
|
||||
|
||||
2014-01-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega256RFR2 et al.): Fix EEPROM size.
|
||||
|
||||
2014-01-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
[bug #41357] OS X: Avrdude messes with the usb stack?
|
||||
* usb_libusb.c (usbdev_close): Only issue the usb_reset() for
|
||||
Linux systems, as these are the only ones that seem to require
|
||||
it under some circumstances.
|
||||
|
||||
2014-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libelf): check against elf_getshdrstrndx() rather
|
||||
than just elf_begin() only, so it is clear we found a sufficiently
|
||||
recent libelf to work with.
|
||||
|
||||
2014-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Alan Horstmann:
|
||||
bug #40897: AT Mega2560 not correctly programmed with stk500(v1) ISP (solution patch)
|
||||
* stk500.c: Implement extended address byte handling.
|
||||
* avrdude.conf.in (ATmega2560): enable stk500_devcode so
|
||||
STK500v1 protocol actually starts at all.
|
||||
|
||||
2014-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip1.c: Implement the meat of FLIP version 1 protocol.
|
||||
* avrdude.1: Document the new protocol.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2014-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip2.c (flip2_page_erase): Remove unimplemented function.
|
||||
* dfu.h: Correctly conditionalize <usb.h> vs. <lusb0_usb.h>;
|
||||
add adjustable timeout (struct dfu_dev); add dfu_abort()
|
||||
* dfu.c (dfu_abort): New function; implement adjustable timeout.
|
||||
|
||||
2014-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libhid): Turn from AC_TRY_RUN into
|
||||
AC_TRY_COMPILE, so it also works for cross-compilation
|
||||
setups.
|
||||
|
||||
2014-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* dfu.c (dfu_init): Move the descriptor checks up into the
|
||||
FLIP protocol implementation.
|
||||
* flip2.c (flip2_initialize): (Dito.)
|
||||
* flip1.c (flip1_initialize): (Dito.)
|
||||
|
||||
2014-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip2.c: Rename from flip.c
|
||||
* flip2.h: Rename from flip.h
|
||||
* Makefile.am: Reflect the renaming.
|
||||
* dfu.c: Update information how to get GPL.
|
||||
* dfu.h: (Dito.)
|
||||
|
||||
2014-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip.c (flip2_initialize): Check user is running on an Xmega
|
||||
device.
|
||||
|
||||
2014-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip.c: Added some verbose-level messages (-vv)
|
||||
* dfu.c: Added some verbose-level messages (-vvvv)
|
||||
|
||||
2014-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Kirill Levchenko:
|
||||
patch #7896: DFU FLIPv2 programming support
|
||||
* pgm_type.c: Add the flip2 programmer type.
|
||||
* config_gram.y: Allow for the usbid keyword in a device definition.
|
||||
* avrdude.conf.in: Add usbpid values to those Xmega devices where
|
||||
applicable.
|
||||
* avrpart.h: Add usbpid device field.
|
||||
* dfu.c: (New file.)
|
||||
* dfu.h: (New file.)
|
||||
* flip.c: (New file.)
|
||||
* flip.h: (New file.)
|
||||
* Makefile.am: Add new files.
|
||||
* doc/avrdude.texi: Document the changes.
|
||||
* avrdude.1: (Dito.)
|
||||
|
||||
2014-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ChangeLog-2013: Annual changelog rotation.
|
||||
54
src/avrdude/ChangeLog-2015
Normal file
54
src/avrdude/ChangeLog-2015
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
2015-12-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1 (-C): Do not suggest users might change the
|
||||
default config file. It will be overwritten by updates.
|
||||
|
||||
2015-12-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
* ser_posix.c: Back out change from patch #8380
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.2.
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.2.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
bug #45727: Wrong atmega8u2 flash parameters
|
||||
* avrdude.conf.in (ATmega8U2): correct page and block size
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46020: Add TIAO TUMPA to the conf file.
|
||||
* avrdude.conf.in (tumpa): New entry.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
* avrdude.conf.in (ATtiny25/45/85): add read pattern for lock bits
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (libavrdude_a_SOURCES): reflect recent changes
|
||||
(pgm.h is gone, config.h is new).
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #44717: avrdude creates empty flash dump
|
||||
* update.c (do_op): When about to write an empty flash dump file,
|
||||
warn about this to avoid surprises.
|
||||
* avrdude.1: Document the truncation of trailing 0xFF bytes for
|
||||
flash memory areas.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Annual ChangeLog rotation.
|
||||
206
src/avrdude/Makefile.am
Normal file
206
src/avrdude/Makefile.am
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
#
|
||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
||||
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog \
|
||||
ChangeLog-2001 \
|
||||
ChangeLog-2002 \
|
||||
ChangeLog-2003 \
|
||||
ChangeLog-2004-2006 \
|
||||
ChangeLog-2007 \
|
||||
ChangeLog-2008 \
|
||||
ChangeLog-2009 \
|
||||
ChangeLog-2010 \
|
||||
ChangeLog-2011 \
|
||||
ChangeLog-2012 \
|
||||
ChangeLog-2013 \
|
||||
avrdude.1 \
|
||||
avrdude.spec \
|
||||
bootstrap
|
||||
|
||||
CLEANFILES = \
|
||||
config_gram.c \
|
||||
config_gram.h \
|
||||
lexer.c
|
||||
|
||||
BUILT_SOURCES = $(CLEANFILES)
|
||||
|
||||
#SUBDIRS = doc @WINDOWS_DIRS@
|
||||
#DIST_SUBDIRS = doc windows
|
||||
|
||||
# . lets build this directory before the following in SUBDIRS
|
||||
SUBDIRS = .
|
||||
# doc comes here, and we want to use the built avrdude to generate the parts list
|
||||
SUBDIRS += @SUBDIRS_AC@
|
||||
SUBDIRS += @WINDOWS_DIRS@
|
||||
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
libavrdude_la_CPPFLAGS = $(libavrdude_a_CPPFLAGS)
|
||||
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
|
||||
libavrdude_la_CFLAGS = $(libavrdude_a_CFLAGS)
|
||||
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBHIDAPI@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
noinst_LIBRARIES = libavrdude.a
|
||||
lib_LTLIBRARIES = libavrdude.la
|
||||
|
||||
# automake thinks these generated files should be in the distribution,
|
||||
# but this might cause trouble for some users, so we rather don't want
|
||||
# to have them there.
|
||||
#
|
||||
# See
|
||||
#
|
||||
# https://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=15536
|
||||
#
|
||||
# for why we don't want to have them.
|
||||
dist-hook:
|
||||
rm -f \
|
||||
$(distdir)/lexer.c \
|
||||
$(distdir)/config_gram.c \
|
||||
$(distdir)/config_gram.h
|
||||
|
||||
libavrdude_a_SOURCES = \
|
||||
config_gram.y \
|
||||
lexer.l \
|
||||
arduino.h \
|
||||
arduino.c \
|
||||
avr.c \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
avrdude.h \
|
||||
avrftdi.c \
|
||||
avrftdi.h \
|
||||
avrftdi_private.h \
|
||||
avrftdi_tpi.c \
|
||||
avrftdi_tpi.h \
|
||||
avrpart.c \
|
||||
bitbang.c \
|
||||
bitbang.h \
|
||||
buspirate.c \
|
||||
buspirate.h \
|
||||
butterfly.c \
|
||||
butterfly.h \
|
||||
config.c \
|
||||
config.h \
|
||||
confwin.c \
|
||||
crc16.c \
|
||||
crc16.h \
|
||||
dfu.c \
|
||||
dfu.h \
|
||||
fileio.c \
|
||||
flip1.c \
|
||||
flip1.h \
|
||||
flip2.c \
|
||||
flip2.h \
|
||||
freebsd_ppi.h \
|
||||
ft245r.c \
|
||||
ft245r.h \
|
||||
jtagmkI.c \
|
||||
jtagmkI.h \
|
||||
jtagmkI_private.h \
|
||||
jtagmkII.c \
|
||||
jtagmkII.h \
|
||||
jtagmkII_private.h \
|
||||
jtag3.c \
|
||||
jtag3.h \
|
||||
jtag3_private.h \
|
||||
libavrdude.h \
|
||||
linuxgpio.c \
|
||||
linuxgpio.h \
|
||||
linux_ppdev.h \
|
||||
lists.c \
|
||||
my_ddk_hidsdi.h \
|
||||
par.c \
|
||||
par.h \
|
||||
pgm.c \
|
||||
pgm_type.c \
|
||||
pickit2.c \
|
||||
pickit2.h \
|
||||
pindefs.c \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
ppiwin.c \
|
||||
safemode.c \
|
||||
serbb.h \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
ser_avrdoper.c \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
solaris_ecpp.h \
|
||||
stk500.c \
|
||||
stk500.h \
|
||||
stk500_private.h \
|
||||
stk500v2.c \
|
||||
stk500v2.h \
|
||||
stk500v2_private.h \
|
||||
stk500generic.c \
|
||||
stk500generic.h \
|
||||
tpi.h \
|
||||
usbasp.c \
|
||||
usbasp.h \
|
||||
usbdevs.h \
|
||||
usb_hidapi.c \
|
||||
usb_libusb.c \
|
||||
usbtiny.h \
|
||||
usbtiny.c \
|
||||
update.c \
|
||||
wiring.h \
|
||||
wiring.c
|
||||
libavrdude_la_SOURCES = $(libavrdude_a_SOURCES)
|
||||
libavrdude_la_LDFLAGS = -version-info 1:0
|
||||
|
||||
include_HEADERS = libavrdude.h
|
||||
|
||||
avrdude_SOURCES = \
|
||||
main.c \
|
||||
term.c \
|
||||
term.h
|
||||
|
||||
man_MANS = avrdude.1
|
||||
|
||||
sysconf_DATA = avrdude.conf
|
||||
|
||||
install-exec-local: backup-avrdude-conf
|
||||
|
||||
distclean-local:
|
||||
rm -f avrdude.conf
|
||||
|
||||
# This will get run before the config file is installed.
|
||||
backup-avrdude-conf:
|
||||
@echo "Backing up avrdude.conf in ${DESTDIR}${sysconfdir}"
|
||||
@if test -e ${DESTDIR}${sysconfdir}/avrdude.conf; then \
|
||||
cp -pR ${DESTDIR}${sysconfdir}/avrdude.conf \
|
||||
${DESTDIR}${sysconfdir}/avrdude.conf.bak; \
|
||||
fi
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
54
src/avrdude/Makefile.standalone
Normal file
54
src/avrdude/Makefile.standalone
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
TARGET = avrdude-slic3r
|
||||
|
||||
SOURCES = \
|
||||
arduino.c \
|
||||
avr.c \
|
||||
avrpart.c \
|
||||
avr910.c \
|
||||
bitbang.c \
|
||||
buspirate.c \
|
||||
butterfly.c \
|
||||
config.c \
|
||||
config_gram.c \
|
||||
crc16.c \
|
||||
fileio.c \
|
||||
lexer.c \
|
||||
linuxgpio.c \
|
||||
lists.c \
|
||||
pgm.c \
|
||||
pgm_type.c \
|
||||
pickit2.c \
|
||||
pindefs.c \
|
||||
safemode.c \
|
||||
ser_avrdoper.c \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
stk500.c \
|
||||
stk500generic.c \
|
||||
stk500v2.c \
|
||||
term.c \
|
||||
update.c \
|
||||
wiring.c \
|
||||
main.c \
|
||||
main-standalone.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
CFLAGS = -std=c99 -Wall -D_BSD_SOURCE -D_DEFAULT_SOURCE -O3 -DNDEBUG -fPIC
|
||||
LDFLAGS = -lm
|
||||
|
||||
CC = gcc
|
||||
RM = rm
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) -o ./$@ $(OBJECTS) $(LDFLAGS)
|
||||
|
||||
$(OBJECTS): %.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
$(RM) -f $(OBJECTS) $(TARGET)
|
||||
913
src/avrdude/NEWS
Normal file
913
src/avrdude/NEWS
Normal file
|
|
@ -0,0 +1,913 @@
|
|||
$Id$
|
||||
|
||||
Approximate change log for AVRDUDE by version.
|
||||
|
||||
(For more detailed changes, see the ChangeLog file.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Current:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- libhidapi support (part of patch #8717)
|
||||
- use libhidapi as (optional) transport for CMSIS-DAP compliant
|
||||
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- ehajo-isp (commercial version of USBtiny)
|
||||
|
||||
* Bugfixes:
|
||||
bug #47550: Linux GPIO broken
|
||||
|
||||
* Internals:
|
||||
|
||||
|
||||
Version 6.3:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Backout of
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
It broke the functionality in too many situations
|
||||
(bug #46610/46483)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega48PB, ATmega88PB, ATmega168PB
|
||||
- ATtiny28 (HVPP-only device)
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- Atmel mEDBG: xplainedmini, xplainedmini_dw
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
- bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
- patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
- patch #8735: ATtiny28 support in avrdude.conf
|
||||
- patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
- patch #8895: Spelling in 6.2 code
|
||||
|
||||
|
||||
Version 6.2:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- The stk500v2 implementation now uses its own higher-level
|
||||
command implementation for byte-wide access, rather than the
|
||||
historic SPI_MULTI command where all the low-level ISP
|
||||
implementation had to be assembled manually inside AVRDUDE. In
|
||||
addition to the traditional STK500, this implementation is also
|
||||
used by all the more modern Atmel tools (AVRISPmkII, JTAGICEmkII
|
||||
in ISP mode, STK600 in ISP mode).
|
||||
|
||||
- The -B option can be suffixed with "Hz", "kHz", or "MHz", in
|
||||
order to specify a bitclock frequency rather than period.
|
||||
|
||||
- Print part id after signature (patch #8440 )
|
||||
|
||||
- buspirate: Also support "cpufreq" extended parameter
|
||||
in binary mode (patch #8504 )
|
||||
|
||||
- The "-P net:" syntax (forwarding of serial data over TCP) is now
|
||||
also implemented for Win32 systems.
|
||||
|
||||
- Allow for arbitrary serial baudrates under Linux (OSX and *BSD
|
||||
could already handle it).
|
||||
|
||||
|
||||
* New devices supported:
|
||||
- AT90PWM216 (bug #42310: New part description for AT90PWM216)
|
||||
- ATmega32M1 (patch #7694 Add support for the atmega32m1)
|
||||
|
||||
* New programmers supported:
|
||||
- ftdi_syncbb
|
||||
+ uncompatino, ttl232r (FTDI TTL232R-5V with ICSP adapter)
|
||||
(patch #8529 2 more ftdi_syncbb devices)
|
||||
|
||||
* Bugfixes
|
||||
- bug #45727: Wrong atmega8u2 flash parameters
|
||||
- bug #46020: Add TIAO TUMPA to the conf file.
|
||||
- bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
- bug #42337 avrdude.conf updates for UM232H/CM232H
|
||||
- bug #42056: double free or corruption triggered at exit
|
||||
- bug #42158: Linux GPIO - Source Typo
|
||||
- bug #42516 spelling-error-in-binary
|
||||
- patch #8419 fix ftdi_syncbb hang with libftdi 1
|
||||
- bug #43002 usbasp debug output typo
|
||||
- patch #8511 Fix reset on FT245R
|
||||
- bug #40142 Floating point exception on Ubuntu 10.04
|
||||
- bug #22248: Read efuse error (partial fix)
|
||||
- bug #42267: jtag3isp fails to read lock and fuse bytes directly
|
||||
after changing lock byte
|
||||
- bug #41561: AVRDUDE 6.0.1/USBasp doesn't write first bytes of
|
||||
flash page
|
||||
- bug #43078: AVRDUDE crashes after sucessfully reading/writing eeprom
|
||||
- bug #43137: Writing and reading incorrect pages when using jtagicemkI
|
||||
- bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
- bug #42908: no external reset at JTAGICE3
|
||||
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
- bug #44717: avrdude creates empty flash dump
|
||||
|
||||
* Internals:
|
||||
- Removing exit calls from config parser
|
||||
- bug #42662 clang warnings under FreeBSD 10.x
|
||||
|
||||
Version 6.1:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
- Atmel EDBG protocol support added (JTAGICE3, XplainedPro, Atmel-ICE)
|
||||
|
||||
* New programmers supported:
|
||||
- Atmel DFU, using FLIP protocol version 1 (AT90USB and ATmega*U* devices),
|
||||
or version 2 (Xmega devices)
|
||||
- Atmel-ICE (ARM/AVR), JTAG, PDI, debugWIRE, ISP modi
|
||||
|
||||
* Bugfixes
|
||||
- bug #40055: AVRDUDE segfaults when writing eeprom
|
||||
- bug #40085: Typo fix in fuses report (for 6.1-svn-20130917)
|
||||
- bug #40782: Verify errors for object size > 16 k on x32e5 due
|
||||
to typo in avrdude.conf
|
||||
- bug #40817: Elf file support (possibly) not working on 6.0.1 windows build
|
||||
- bug #40897: AT Mega2560 not correctly programmed with stk500(v1)
|
||||
ISP (solution patch)
|
||||
- bug #41357: OS X: Avrdude messes with the usb stack?
|
||||
- bug #41402: dfu.c missing include <stdint.h>
|
||||
- patch #7896: DFU FLIPv2 programming support
|
||||
- patch #XXXX: xxx
|
||||
|
||||
* Internals:
|
||||
- (Some) programmers can take a list of USB PIDs now.
|
||||
|
||||
|
||||
Version 6.0:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Programmer types in configuration file are no longer keywords but
|
||||
specified as string.
|
||||
|
||||
So you need to change 'type = XYZ;' to 'type = "XYZ";' in own
|
||||
config files. (internal: The parser does not need to know all
|
||||
programmer types now, new programmers will update only the table
|
||||
in pgm_type.c.)
|
||||
|
||||
- The erase cycle counter (formerly options -y / -Y) has been
|
||||
removed.
|
||||
|
||||
- Specifying a -U option without a memory type (short form of
|
||||
option argument list) now defaults to "application" memory for
|
||||
Xmega devices, and "flash" for everything else. This ensures
|
||||
the Xmega bootloader is not accidentally touched.
|
||||
|
||||
- For programmers that support it, the default erase method is a
|
||||
page erase now, rather than a chip erase (Xmega only).
|
||||
|
||||
- Keep track of input file contents
|
||||
|
||||
Memory segments are being tracked to remember whether they've
|
||||
been actually read from a file. Only segments that came from a
|
||||
file are being programmed into the device, or considered for
|
||||
verification. This drastically improves handling speed for
|
||||
sparse files (e.g. files that have a second bootloader segment),
|
||||
and it ensures the device contents is actually compared for
|
||||
everything mentioned in the file (even in case the file has
|
||||
large 0xFF blocks).
|
||||
|
||||
- The -U option now accepts ELF files as input files, and extracts
|
||||
the appropriate section contents that matches the requested memory
|
||||
region. To enable this feature, the host system used for the
|
||||
compilation must have a libelf around, including the respective
|
||||
header files (i.e., package "libelf-devel" on many Linux systems).
|
||||
|
||||
- Programmers and parts lists
|
||||
|
||||
They are now sorted at output with '-c ?'/'-p ?'. (patch #7671:
|
||||
Sorting programmers and parts lists for console output)
|
||||
|
||||
Programmers and parts lists in documentation generated from lists
|
||||
mentioned above. (patch #7687: Autogenerating programmers and
|
||||
parts lists for docs)
|
||||
|
||||
Output list of programmer types with '-c ?type', add list to
|
||||
documentation
|
||||
|
||||
- Configuration files now accepts parent parts/programmers, parts
|
||||
starting with '.' (eg. .xmega) are not included in output parts
|
||||
list and can be used as abstract parents
|
||||
|
||||
(bug #34302: Feature request : device configuration with parent classes)
|
||||
(patch #7688: Implement parent programmers feature)
|
||||
|
||||
- Additional config files which are read after default can be
|
||||
specified on command line using '-C +filename'
|
||||
|
||||
(patch #7699 Read additional config files)
|
||||
|
||||
- "Safemode" can now be turned off by default from within a
|
||||
configuration file (like ~/.avrduderc).
|
||||
|
||||
- The new option -l logfile allows to redirect diagnostic messages
|
||||
to a logfile rather than stderr. Useful to record debugging
|
||||
traces, in particular in environments which do not offer
|
||||
shell-style redirection functionality for standard streams.
|
||||
|
||||
- When leaving debugWIRE mode, immediately retry with ISP rather
|
||||
than bailing out completely.
|
||||
|
||||
- The USBasp programmer implementation now supports detailed traces
|
||||
with -vvv, and device communication traces with -vvvv.
|
||||
|
||||
- The "verbose" terminal mode command allows to query or modify the
|
||||
verbosity level.
|
||||
|
||||
* New devices supported:
|
||||
- ATmega48P (patch #7629 add support for atmega48p)
|
||||
- AT90PWM316 (bug #21797: AT90PWM316: New part description)
|
||||
- ATxmega16D4, ATxmega32D4, ATxmega64D4, ATxmega128D4
|
||||
- ATmega256RFR2, ATmega128RFR2, ATmega64RFR2, ATmega2564RFR2,
|
||||
ATmega1284RFR2, ATmega644RFR2
|
||||
- ATtiny1634
|
||||
- ATxmega128A1U, ATxmega128A3U, ATxmega128A4U, ATxmega128B1,
|
||||
ATxmega128B3, ATxmega128C3, ATxmega128D3, ATxmega16A4U,
|
||||
ATxmega16C4, ATxmega192A3U, ATxmega192C3, ATxmega192D3,
|
||||
ATxmega256A3BU, ATxmega256A3U, ATxmega256C3, ATxmega256D3,
|
||||
ATxmega32A4U, ATxmega32C4, ATxmega384C3, ATxmega384D3,
|
||||
ATxmega64A1U, ATxmega64A3U, ATxmega64A4U, ATxmega64B1,
|
||||
ATxmega64B3, ATxmega64C3, ATxmega64D3
|
||||
- ATtiny43U
|
||||
- ATmega406
|
||||
- ATxmega8E5, ATxmega16E5, ATxmega32E5
|
||||
- ATtiny20, ATtiny40
|
||||
|
||||
|
||||
* New programmers supported:
|
||||
- linuxgpio
|
||||
+ any (embedded) Linux system with 4 GPIOs available can be used
|
||||
as a programmer with little or no additional hardware.
|
||||
|
||||
- avrftdi
|
||||
+ o-link (patch #7672 adding support for O-Link (FTDI based
|
||||
JTAG) as programmer)
|
||||
+ 4232h (patch #7715 FT4232H support)
|
||||
- TPI support
|
||||
+ openmoko (bug #37977 Support for Openmoko Debug Board)
|
||||
|
||||
- usbasp
|
||||
+ nibobee (previously specified as '-c usbasp -P nibobee)
|
||||
+ usbasp-clone (same as usbasp but ignores vendor and product
|
||||
string, checks only vid/pid)
|
||||
|
||||
- ftdi_syncbb (new type for synchronous bitbanging with ft232r/ft245r)
|
||||
+ ft245r (FT245R Synchronous BitBang, miso = D1, sck = D0, mosi
|
||||
= D2, reset = D4)
|
||||
+ ft232r (FT232R Synchronous BitBang, miso = RxD, sck = RTS,
|
||||
mosi = TxD, reset = DTR)
|
||||
+ bwmega (BitWizard ftdi_atmega builtin programmer, miso = DSR,
|
||||
sck = DCD, mosi = CTS, reset = RI)
|
||||
+ arduino-ft232r (Arduino: FT232R connected to ISP, miso = CTS
|
||||
X3(1), sck = DSR X3(2), mosi = DCD X3(3), reset = RI X3(4))
|
||||
+ diecimila (alias for arduino-ft232r)
|
||||
|
||||
- pickit2
|
||||
|
||||
- Atmel JTAGICE3
|
||||
|
||||
- buspirate_bb (TPI programming using the BusPirate in bitbang mode)
|
||||
|
||||
* Bugfixes
|
||||
- bug #34027: avrdude AT90S1200 Problem
|
||||
- bug #34518: loading intel hex files > 64k using record-type 4
|
||||
- patch #7667: Minor memory handling fixes
|
||||
- patch #7680: Fixing timeout problem in ser_recv in ser_win32.c
|
||||
- patch #7693: Fix config file atmel URLs (+ URLs in
|
||||
avrdude.texi and avrpart.h)
|
||||
- bug #21663: AT90PWM efuse incorrect, bug #30438: efuse bits
|
||||
written as 0 on at90pwmxx parts
|
||||
- bug #35261: avrftdi uses wrong interface in avrftdi_paged_(write|load)
|
||||
- patch #7437 modifications to Bus Pirate module
|
||||
- patch #7686 Updating buspirate ascii mode to current firmware,
|
||||
use AUX as clock generator, and setting of serial receive
|
||||
timeout
|
||||
- bug #34768 Proposition: Change the name of the AVR32 devices
|
||||
- patch #7718: Merge global data of avrftdi in a private data
|
||||
structure
|
||||
- bug #35208: avrdude 5.11 on freebsd 8.2-STABLE does not reset
|
||||
Arduino Uno properly
|
||||
- bug #34518: loading intel hex files > 64k using record-type 4
|
||||
(Extended Linear Address Record)
|
||||
- bug #34027: avrdude AT90S1200 Problem
|
||||
- bug #30451: Accessing some Xmega memory sections gives not
|
||||
supported error
|
||||
- bug #28744: Can't load bootloader to xmega128a1
|
||||
- bug #29019: pagel/bs2 warning when uploading using stk500 to xmega
|
||||
- bug #30756: When setting SUT to 64ms on XMEGA, avrdude doesn't
|
||||
read device signature
|
||||
- bug #37265: wrong page sizes for XMega64xx in avrdude.conf
|
||||
- bug #37942: Latest SVN can't program in dragon_jtag mode
|
||||
- patch #7876 JTAGICE mkII fails to connect to attiny if debugwire
|
||||
is enabled AND target has a very slow clock
|
||||
- bug #39893: Verification failure with AVRISPmkII and Xmega
|
||||
- bug #38713: Compilation of the documentation breaks with texinfo-5
|
||||
- bug #38023: avrdude doesn't return an error code when attempting
|
||||
to upload an invalid Intel HEX file
|
||||
- bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
- bug #35800: Compilation error on certain systems if parport is disabled
|
||||
- bug #38307: Can't write usersig of an xmega256a3
|
||||
- bug #38580: Current svn head, xmega and fuses, all fuses tied to fuse0
|
||||
- bug #39691: Buffer overrun when reading EEPROM byte with JTAGICE3
|
||||
- bug #38951: AVR109 use byte offset instead of word offset
|
||||
- patch #7769: Write flash fails for AVR910 programmers
|
||||
- bug #38732: Support for ATtiny1634
|
||||
- bug #36901: flashing Atmega32U4 EEPROM produces garbage on chip
|
||||
- bug #28344: chip_erase_delay too short for ATmega324P, 644, 644P, and 1284P
|
||||
- bug #34277: avrdude reads wrong byte order if using avr911 (aka butterfly)
|
||||
- bug #35456: The progress bar for STK500V2 programmer is "wrong".
|
||||
- patch #5708: avrdude should make 10 synchronization attempts instead of just one
|
||||
- patch #7606: ATtiny43u support
|
||||
- patch #7657: Add ATmega406 support for avrdude using DRAGON + JTAG
|
||||
- bug #35474: Feature request: print fuse values in safemode output.
|
||||
- patch #7710: usb_libusb: Check VID/PID before opening device
|
||||
- [no-id]: Fix SCK period adjustment for STK500v2
|
||||
- bug #40040: Support for ATtiny20 and ATtiny40
|
||||
|
||||
* Internals:
|
||||
|
||||
- Restructuring and compacting programmer definition part of
|
||||
grammar for config file.
|
||||
- Cleanup of parser code, removing unused definitions/
|
||||
functions. Using yylex_destroy if available.
|
||||
- Fixed some more memory leaks, added cleanup code at program exit
|
||||
(to minimize the number of non-freed memory blocks reported by
|
||||
valgrind)
|
||||
- Fixed some findings reported by cppcheck.
|
||||
|
||||
Version 5.11:
|
||||
|
||||
* New devices supported:
|
||||
- ATmega88P/168P
|
||||
- ATmega8U2/16U2/32U2
|
||||
- ATtiny4313
|
||||
|
||||
* New programmers supported:
|
||||
- TPI programming through bitbang programmers (both, serial
|
||||
and parallel ones)
|
||||
- FT2232 (and relatives) based programmers (MPSSE bitbang mode)
|
||||
- Wiring environment (http://wiring.org.co/)
|
||||
- butterfly-style bootloader of the Mikrokopter.de device
|
||||
|
||||
* Bugfixes
|
||||
|
||||
|
||||
Version 5.10:
|
||||
|
||||
* Bugfixes
|
||||
- bug #28660: Problem with loading intel hex rom files that exceed
|
||||
0x10000 bytes
|
||||
- see ChangeLog for further details
|
||||
|
||||
* New Features
|
||||
- (JTAG ICE / AVR Dragon) apply external reset if JTAG ID could
|
||||
not be read
|
||||
|
||||
Version 5.9:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AVR32A0512 (JTAGMKII only)
|
||||
- ATmega32U4
|
||||
- ATtiny4
|
||||
- ATtiny5
|
||||
- ATtiny9
|
||||
- ATtiny10
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- BusPirate
|
||||
- Arduino
|
||||
- JTAGICEmkII and AVR Dragon in PDI mode (ATxmega devices)
|
||||
- STK600 and AVRISP mkII in TPI mode (ATtiny4/5/9/10)
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- see ChangeLog and ChangeLog-2009 for details
|
||||
|
||||
Version 5.8:
|
||||
|
||||
* Bugfixes; most importantly, fix a serious memory corruption for
|
||||
that JTAG ICE mkII and AVR Dragon in ISP/HVSP/PP mode.
|
||||
|
||||
Version 5.7:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATXMEGA64A1
|
||||
- ATXMEGA192A1
|
||||
- ATXMEGA256A1
|
||||
- ATXMEGA64A3
|
||||
- ATXMEGA128A3
|
||||
- ATXMEGA192A3
|
||||
- ATXMEGA256A3
|
||||
- ATXMEGA256A3B
|
||||
- ATXMEGA16A4
|
||||
- ATXMEGA32A4
|
||||
- ATXMEGA64A4
|
||||
- ATXMEGA128A4
|
||||
|
||||
* Major Xmega fixes for the JTAG ICE mkII (patch #6825)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.6:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB82
|
||||
- AT90USB162
|
||||
- ATtiny88
|
||||
- ATmega328P
|
||||
- ATmega1284P
|
||||
- ATmega128RFA1
|
||||
- ATxmega128A1 rev D
|
||||
- ATxmega128A1
|
||||
- ATxmega256A3
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- AT89ISP cable (patch #6069)
|
||||
- Arduino
|
||||
|
||||
* Add support for the -x option to pass extended parameters to the
|
||||
programmer backend.
|
||||
|
||||
* Add support for JTAG daisy-chains, using the -x daisychain=
|
||||
option.
|
||||
|
||||
* Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
|
||||
ATmega), using either ISP or high-voltage programming modes.
|
||||
|
||||
* Add support for the -x devcode extended parameter to the avr910
|
||||
programmer, to allow overriding the device code sent to the
|
||||
programmer.
|
||||
|
||||
* Add support for the Crossbow MIB510 programmer (patch #6074, #6542).
|
||||
|
||||
* Add support to bootstrap with GNU autoconf 2.61, and automake 1.10,
|
||||
respectively.
|
||||
|
||||
* Add support for ATxmega128A1 (including the revision D engineering
|
||||
samples) for STK600 and AVRISPmkII tools using PDI
|
||||
|
||||
* The option combination -tF now enters terminal mode even if the
|
||||
device initialization failed, so the user can modify programmer
|
||||
parameters (like Vtarget).
|
||||
|
||||
* Add preliminary support for ATxmega128A1 for the JTAG ICE mkII using
|
||||
JTAG.
|
||||
|
||||
* Add support for direct SPI transfers (bug #25156).
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.5:
|
||||
|
||||
* Add support for the USBtinyISP programmer (patch #6233)
|
||||
|
||||
* Add support for the C2N232I serial bitbang programmer (patch #6121)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.4:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90PWM2B/AT90PWM3B
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
* Source code rearranged so that the functionality is now built
|
||||
into a libavrdude.a library where main.c is currently the only
|
||||
existing frontend.
|
||||
|
||||
* Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
Version 5.3.1:
|
||||
|
||||
* Add support for the AVR Dragon (all modes: ISP, JTAG, HVSP, PP,
|
||||
debugWire).
|
||||
|
||||
* Add support for debugWire (both, JTAG ICE mkII, and AVR Dragon).
|
||||
|
||||
* Add support for the AVR Doper USB HID-class programmer.
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.2:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB646/647/1286/1287
|
||||
- ATmega2560/2561
|
||||
- ATmega325/3250/645/6450
|
||||
- ATtiny11 (HVSP only device)
|
||||
- ATtiny261/461/861
|
||||
|
||||
* Fixed paged flash write operations for AT90PWMx devices
|
||||
(error in datasheet).
|
||||
|
||||
* Add signature verification.
|
||||
|
||||
* Add high-voltage mode programming for the STK500 (both,
|
||||
parallel, and high-voltage serial programming).
|
||||
|
||||
* Add support for using the JTAG ICE mkII as a generic ISP
|
||||
programmer.
|
||||
|
||||
* Allow for specifying the ISP clock delay as an option for
|
||||
bit-bang programming adapters.
|
||||
|
||||
* Add support for Thomas Fischl's USBasp low-cost USB-attached
|
||||
programmer.
|
||||
|
||||
* The "stk500" programmer type is now implemented as a stub
|
||||
that tries to probe for either "stk500v1" or "stk500v2".
|
||||
|
||||
* Many bugfixes.
|
||||
|
||||
Version 5.1:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega640/1280/1281
|
||||
- ATtiny24/44/84
|
||||
|
||||
* JTAG mkII support now works with libusb-win32, too
|
||||
|
||||
* JTAG ICE mkI support has been added
|
||||
|
||||
* Solaris support has been added (including ecpp(7D) parallel-port
|
||||
bit-bang mode)
|
||||
|
||||
|
||||
Version 5.0:
|
||||
|
||||
* Support for JTAGICE MkII device
|
||||
|
||||
* Support for STK500 Version 2 Protocol
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90CAN128
|
||||
- ATmega329x/649x
|
||||
- ATmega164/324/644
|
||||
- AT90PWM2/3,
|
||||
- ATmega164/324/644
|
||||
- ATmega329x/649x
|
||||
- ATtiny25/45/85
|
||||
|
||||
* Support for serial bit-bang adapters: Ponyprog serial, UISP DASA,
|
||||
UISP DASA3.
|
||||
|
||||
* DAPA programmer pinout supported
|
||||
|
||||
* New "safemode" feature where fuse bits are verified before exit
|
||||
and if possible recovered if they have changed. This is intended
|
||||
to protect against changed fuses which were not requested which is
|
||||
reported to sometimes happen due to improper power supply or other
|
||||
reasons.
|
||||
|
||||
* Various fixes for avr910 and butterfly programmers
|
||||
|
||||
* Full support for AVR109 boot loaders (butterfly)
|
||||
|
||||
* Adding -q -q suppresses most terminal output
|
||||
|
||||
|
||||
Version 4.4.0:
|
||||
|
||||
* Native Win32 support: The windows build doesn't need Cygwin
|
||||
anymore. Additionally, the delay timing on windows should be
|
||||
more accurate now.
|
||||
Contributed by Martin Thomas
|
||||
|
||||
* Add support for
|
||||
- ATmega48, ATmega88 (contributed by Galen Seitz)
|
||||
- ATtiny2313 (contributed by Bob Paddock)
|
||||
- ATtiny13 (contributed by Pawel Moll)
|
||||
|
||||
* Added command to change the SCK of STK500-programmers. Now it
|
||||
is possible to program uC with slow oscillator.
|
||||
Contributed by Galen Seitz
|
||||
|
||||
* Baudrate for serial programmers (STK500 and AVR910) is
|
||||
configurable in the config or at the command-line.
|
||||
This way some more tweaked bootloaders and programmers can be used.
|
||||
|
||||
* Deprecated options have been removed.
|
||||
Now the "-U" option must be used.
|
||||
|
||||
* MacOS X now supported by default.
|
||||
|
||||
Version 4.3.0:
|
||||
|
||||
* Added support for "Butterfly" evaluation board.
|
||||
|
||||
* Make cycle-count work with AVR910-programmers.
|
||||
|
||||
* Added "Troubleshooting"-Appendix to the manual.
|
||||
|
||||
* Add ATmega8515 support.
|
||||
Contributed by: Matthias Weißer <matthias@matwei.de>
|
||||
|
||||
* Add ATmega64 support.
|
||||
Contributed by: Erik Christiansen <erik@dd.nec.com.au>
|
||||
|
||||
* Improved polling algorithm to speed up
|
||||
programming of byte oriented parallel programmers.
|
||||
Contributed by: Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>
|
||||
|
||||
* Add "fuse" and "lock" definitions for the AT90S8535.
|
||||
|
||||
* STK500 skips empty pages in paged write resulting in faster downloads
|
||||
when there are empty blocks in between code (such as files that contain
|
||||
application code and bootloader code).
|
||||
|
||||
Version 4.2.0:
|
||||
|
||||
* Add basic support for reading and writing fuses via SPI with avr910
|
||||
programmers. Submitted by
|
||||
Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>.
|
||||
|
||||
* Perform an auto erase before programming if the flash memory is
|
||||
anywhere specified to be written by any of the -U requests. Old
|
||||
style memory specification options (-f, -i, -I, -m, and -o) are
|
||||
deprecated in favor of the new -U options. Auto erase is disabled
|
||||
if any of the old-style options (specifically -i and -o) are
|
||||
specified.
|
||||
|
||||
* Add new -U option for specifying programming operations - allows
|
||||
multiple memory operations on a single command line.
|
||||
|
||||
* New progress reporting, looks nicer and is nicer to wrapper
|
||||
environments such as emacs.
|
||||
|
||||
* Fix long-standing timing (verify) problems on Windows platform.
|
||||
Submitted by Alex Shepherd <ashepherd@wave.co.nz>.
|
||||
|
||||
* Add new file format option - 'm' for "immediate mode." In this
|
||||
case, the filename argument of the -o, -i, or -U options is
|
||||
treated as the data for uploading - useful for specifying fuse
|
||||
bits without having to create a single-byte file for uploading.
|
||||
|
||||
* Add support for displaying and setting the various STK500 operational
|
||||
parameters (Vtarget, Varef, Master clock).
|
||||
|
||||
* Add 'picoweb' programming cable programmer.
|
||||
Contributed by Rune Christensen <rune.christensen@adslhome.dk>.
|
||||
|
||||
* Add support for the sp12 programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
|
||||
Version 4.1.0
|
||||
|
||||
* Add support for the Bascom SAMPLE programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
* Add support for avr910 type programmers (mcu00100, pavr avr910, etc).
|
||||
|
||||
* Support new devices: ATmega8535, ATtiny26
|
||||
|
||||
|
||||
Version 4.0.0
|
||||
|
||||
* Now support Linux - added by "Theodore A. Roth" <troth@openavr.org>.
|
||||
|
||||
* Now support Windows - added by "Eric B. Weddington" <eric@ecentral.com>.
|
||||
|
||||
* Use 'configure' scripts to tailor the code to the system avrdude
|
||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
||||
<troth@openavr.org>.
|
||||
|
||||
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||
<tsar@kemford.com>.
|
||||
|
||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||
'bs2' keywords to the config file for this purpose.
|
||||
|
||||
* Add support for the AT90S2343
|
||||
|
||||
* Add support for the ATmega169
|
||||
|
||||
* Add ability to specify system defaults within the config file
|
||||
(default parallel port, default serial port).
|
||||
|
||||
* Specify the default programmer seperately from the programmer
|
||||
definition. This is now done in the config file using the
|
||||
'default_programmer' keyword.
|
||||
|
||||
* Support a per-user config file (~/.avrduderc) so that one can
|
||||
override system wide defaults if desired.
|
||||
|
||||
* Follow the datasheet more closely for several parts in the "retry"
|
||||
code when entering programming mode fails initially. Introduce
|
||||
'retry_pulse' to the config file for this purpose.
|
||||
|
||||
|
||||
|
||||
Version 3.1.0
|
||||
|
||||
* This change represents a name change only. There is currently an
|
||||
effort to port AVRPROG to other platforms including Linux and
|
||||
Windows. Since Atmel's programmer binary that's included within
|
||||
their AVR Studio software is named AVRPROG.EXE on the Windows OS,
|
||||
there is the chance for confusion if we keep calling this program
|
||||
AVRPROG as well. Up until now the name hasn't really been a
|
||||
problem since there was no chance to confuse 'avrprog' on Unix
|
||||
with Atmel's AVRPROG because Atmel's tools only run on Windows.
|
||||
But with the Unix 'avrprog' possibly being ported to Windows, I
|
||||
felt a name change was the best way to avoid problems.
|
||||
|
||||
So - from this point forward, my FreeBSD Unix program formerly
|
||||
known as AVRPROG will subsequently be known as AVRDUDE (AVR
|
||||
Downloader/UploaDEr).
|
||||
|
||||
This change also represents a time when the AVRDUDE sources move
|
||||
from my own private repository to a public repository. This will
|
||||
give other developers a chance to port AVRDUDE to other platforms
|
||||
and extend its functionality to support additional programming
|
||||
hardware, etc.
|
||||
|
||||
So goodbye AVRPROG, welcome AVRDUDE!
|
||||
|
||||
Version 3.0.0
|
||||
|
||||
* Rewrite parts of the code to make it easy to support other types
|
||||
of programmers besides the directly connected parallel port
|
||||
programmer (PPI).
|
||||
|
||||
* Add support for Atmel's STK500 programmer/development board. The
|
||||
STK500's "paged mode" read/write is supported which makes this
|
||||
programmer very fast. This is sorely needed on parts with large
|
||||
memories such as the ATmega128. My 12K test program burns in
|
||||
about 5 seconds, add another 5 to read it back out for
|
||||
verification.
|
||||
|
||||
|
||||
Version 2.1.5:
|
||||
|
||||
* When getting ready to initiate communications with the AVR device,
|
||||
first pull /RESET low for a short period of time before enabling
|
||||
the buffer chip. This sequence allows the AVR to be reset before
|
||||
the buffer is enabled to avoid a short period of time where the
|
||||
AVR may be driving the programming lines at the same time the
|
||||
programmer tries to. Of course, if a buffer is being used, then
|
||||
the /RESET line from the programmer needs to be directly connected
|
||||
to the AVR /RESET line and not via the buffer chip.
|
||||
|
||||
Feature contributed by Rick C. Petty <rick@KIWI-Computer.com>.
|
||||
|
||||
* When in interactive terminal mode and dumping memory using the
|
||||
'dump <memtype>' command without any address information, and the
|
||||
end of memory is reached, wrap back around to zero on the next
|
||||
invocation.
|
||||
|
||||
|
||||
Version 2.1.4:
|
||||
|
||||
* Fix -Y option.
|
||||
|
||||
|
||||
Version 2.1.3:
|
||||
|
||||
* Be backward compatible when reading 2-byte rewrite cycle counters
|
||||
as written by avrprog version 2.1.0. Version 2.1.1 changed over
|
||||
to a 4-byte counter, which caused avrprog versions 2.1.1 and 2.1.2
|
||||
to report a negative count for parts that were initialized using
|
||||
version 2.1.0. Thanks to Joerg Wunsch for noticing this.
|
||||
|
||||
|
||||
Version 2.1.2:
|
||||
|
||||
* Add '-V' option to disable automatic verify check with uploading
|
||||
data.
|
||||
|
||||
|
||||
Version 2.1.1:
|
||||
|
||||
* Fix ATmega128 instruction sequences for reading fuse bits -
|
||||
contributed by Joerg Wunsch.
|
||||
|
||||
* Modify erase-rewrite cycle counter code to use a 4 byte counter
|
||||
instead of a two byte counter.
|
||||
|
||||
|
||||
Version 2.1.0:
|
||||
|
||||
* Implement a per-part erase-rewrite cycle counter; requires the use
|
||||
of two bytes of EEPROM memory.
|
||||
|
||||
|
||||
Version 2.0.5:
|
||||
|
||||
* Support for ATtiny15 - contributed by Asher Hoskins
|
||||
|
||||
|
||||
Version 2.0.4:
|
||||
|
||||
* Config file fixes for various parts.
|
||||
|
||||
|
||||
Version 2.0.3:
|
||||
|
||||
* Work around problem programming fuse bits on parts like the
|
||||
at90s4433 as described in the following errata:
|
||||
|
||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf
|
||||
|
||||
* Add part definition for at90s4414, at90s4433.
|
||||
|
||||
* Add fuse/lock bit memory instructions for the at90s1200,
|
||||
at90s2333, at90s4433 and at90s8515.
|
||||
|
||||
* Fix setting of programmer status LEDs under certain write-fail
|
||||
conditions.
|
||||
|
||||
|
||||
Version 2.0.2 :
|
||||
|
||||
* Fix writing to read-only memories such as the lock bits of the
|
||||
AT90S2313.
|
||||
|
||||
* Copyright updates.
|
||||
|
||||
|
||||
Version 2.0.1 :
|
||||
|
||||
* Use correct parallel port pins for VCC.
|
||||
|
||||
* Add programmer definition for Atmel's STK200.
|
||||
|
||||
* Add programmer definition for the AVR3 board.
|
||||
|
||||
* Fix address bit encoding for many parts.
|
||||
|
||||
* Allow the ``BUFF'' signal to be asserted by multiple pins of the
|
||||
parallel port (like VCC) instead of just one. The STK200 appears
|
||||
to need this feature.
|
||||
|
||||
|
||||
Version 2.0.0 :
|
||||
|
||||
* Add support for programming fuse and lock bits if supported by the
|
||||
part.
|
||||
|
||||
* Move instruction encoding into the config file. Now any part can
|
||||
be supported as long as it uses the same basic serial programming
|
||||
instruction format.
|
||||
|
||||
* Add part definitions for the ATMega163 and ATMega8 devices.
|
||||
|
||||
|
||||
Version 1.4.3 :
|
||||
|
||||
* Mostly internal code cleanup.
|
||||
|
||||
|
||||
Version 1.4.2 :
|
||||
|
||||
* Fixes for ATMega paged memory support.
|
||||
|
||||
* Support for ATMega16 device.
|
||||
|
||||
|
||||
Version 1.4.1 :
|
||||
|
||||
* No functional changes, update to Copyrights only.
|
||||
|
||||
|
||||
Version 1.4.0 :
|
||||
|
||||
* Add part definitions to the config file.
|
||||
|
||||
* Add initial support for Atmel's ATMega paged memory parts.
|
||||
|
||||
* Config file documentation added.
|
||||
|
||||
* Add a definition for the Dontronics DT006 programmer.
|
||||
|
||||
* Fix Intel Hex support for addresses larger than 64k.
|
||||
|
||||
|
||||
Version 1.3.0 :
|
||||
|
||||
* Make programmer pin assignments configurable.
|
||||
|
||||
|
||||
Version 1.2.2 :
|
||||
|
||||
* Initial public release.
|
||||
64
src/avrdude/README
Normal file
64
src/avrdude/README
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
THIS IS A PRUSA3D BRANCH, WORKING AROUND A SPECIFIC PROBLEM
|
||||
IN THE EARLY I3 MK2 USB COMMUNICATION CHIPS.
|
||||
|
||||
Some of the early Prusa3D i3 MK2 printers were shipped with a buggy
|
||||
USB communication controller firmware. This fork of avrdude contains
|
||||
a workaround inside the stk500v2 protocol implementation.
|
||||
|
||||
The workaround depends on a specific behavior of the Arduino AVR 2560
|
||||
bootloader, which is installed on the i3 MK2 printers:
|
||||
|
||||
https://github.com/arduino/Arduino-stk500v2-bootloader
|
||||
|
||||
The avrdude binary modified by Prusa3D could replace the avrdude bianary
|
||||
of arduino to program the RAMBo board. In that case the modified binary
|
||||
is identified by a "-prusa3d" suffix to the version information.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
See the documentation file for the details.
|
||||
|
||||
The latest version of AVRDUDE is always available here:
|
||||
|
||||
http://savannah.nongnu.org/projects/avrdude
|
||||
|
||||
|
||||
Important environment variables for ./configure:
|
||||
================================================
|
||||
|
||||
CPPFLAGS: C preprocessor flags (*not* "C++")
|
||||
|
||||
This is the place to put additional (non-standard) -I options into.
|
||||
For example, if your Windows system has LibUSB-Win32 installed into
|
||||
\\WINDOWS\ProgramFiles\LibUSB-Win32, use
|
||||
|
||||
CPPFLAGS=-I/WINDOWS/ProgramFiles/LibUSB-Win32/include
|
||||
|
||||
to tell configure where to search for the header files. (The use of
|
||||
forward slashes rather than backslashes can often simplify things.
|
||||
Note that the Windows system services internally treat both the same.
|
||||
It's only cmd.exe which requires backslashes as the directory
|
||||
separator.)
|
||||
|
||||
LDFLAGS: Linker options
|
||||
|
||||
This is the place to make additional library locations known to the
|
||||
linker. To continue the above example, use
|
||||
|
||||
LDFLAGS=-L/WINDOWS/ProgramFiles/LibUSB-Win32/lib/gcc
|
||||
|
||||
to make the linker search for "libusb.a" in that directory.
|
||||
|
||||
|
||||
Linux users: make sure the header files are installed
|
||||
=====================================================
|
||||
|
||||
While many Linux distributions install the libraries needed by AVRDUDE
|
||||
(libusb, libelf) by default, they leave out the corresponding header
|
||||
files. Consequently, the configure script won't find them, so these
|
||||
libraries could not be used.
|
||||
|
||||
Usually, the packages with the header files (and static libraries) are
|
||||
derived from the regular package name by appending "-devel". Thus,
|
||||
make sure you have "libusb-devel" and "libelf-devel" installed before
|
||||
running the configure script. (Same goes for libftdi.)
|
||||
206
src/avrdude/ac_cfg.h
Normal file
206
src/avrdude/ac_cfg.h
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/* ac_cfg.h. Generated from ac_cfg.h.in by configure. */
|
||||
/* ac_cfg.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
|
||||
// Edited by hand for usage with Slic3r PE
|
||||
|
||||
#define CONFIG_DIR "CONFIG_DIR"
|
||||
|
||||
|
||||
/* Define to 1 if you have the <ddk/hidsdi.h> header file. */
|
||||
/* #undef HAVE_DDK_HIDSDI_H */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#if defined (WIN32NATIVE)
|
||||
/* #undef HAVE_GETTIMEOFDAY */
|
||||
// We have a gettimeofday() replacement in unistd.cpp (there is also one in ppiwin.c, but that file is written for Cygwin/MinGW)
|
||||
#else
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <hidapi/hidapi.h> header file. */
|
||||
/* #undef HAVE_HIDAPI_HIDAPI_H */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define if ELF support is enabled via libelf */
|
||||
// #define HAVE_LIBELF 1
|
||||
|
||||
/* Define to 1 if you have the <libelf.h> header file. */
|
||||
// #define HAVE_LIBELF_H 1
|
||||
|
||||
/* Define to 1 if you have the <libelf/libelf.h> header file. */
|
||||
/* #undef HAVE_LIBELF_LIBELF_H */
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi */
|
||||
/* #undef HAVE_LIBFTDI */
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi1 */
|
||||
// #define HAVE_LIBFTDI1 1
|
||||
|
||||
/* Define if libftdi supports FT232H, libftdi version >= 0.20 */
|
||||
/* #undef HAVE_LIBFTDI_TYPE_232H */
|
||||
|
||||
/* Define if HID support is enabled via the Win32 DDK */
|
||||
/* #undef HAVE_LIBHID */
|
||||
|
||||
/* Define if HID support is enabled via libhidapi */
|
||||
/* #undef HAVE_LIBHIDAPI */
|
||||
|
||||
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||
// #define HAVE_LIBNCURSES 1
|
||||
|
||||
/* Define to 1 if you have the `readline' library (-lreadline). */
|
||||
// #define HAVE_LIBREADLINE 1
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
/* #undef HAVE_LIBTERMCAP */
|
||||
|
||||
/* Define if USB support is enabled via libusb */
|
||||
// #define HAVE_LIBUSB 1
|
||||
|
||||
/* Define if USB support is enabled via a libusb-1.0 compatible libusb */
|
||||
// #define HAVE_LIBUSB_1_0 1
|
||||
|
||||
/* Define to 1 if you have the <libusb-1.0/libusb.h> header file. */
|
||||
// #define HAVE_LIBUSB_1_0_LIBUSB_H 1
|
||||
|
||||
/* Define to 1 if you have the <libusb.h> header file. */
|
||||
/* #undef HAVE_LIBUSB_H */
|
||||
|
||||
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
|
||||
/* #undef HAVE_LIBWS2_32 */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Linux sysfs GPIO support enabled */
|
||||
/* #undef HAVE_LINUXGPIO */
|
||||
|
||||
/* Define to 1 if you have the <lusb0_usb.h> header file. */
|
||||
/* #undef HAVE_LUSB0_USB_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* parallel port access enabled */
|
||||
// #define HAVE_PARPORT 1
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
// #define HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint_t'. */
|
||||
/* #undef HAVE_UINT_T */
|
||||
|
||||
/* Define to 1 if the system has the type `ulong_t'. */
|
||||
/* #undef HAVE_ULONG_T */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <usb.h> header file. */
|
||||
#define HAVE_USB_H 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define HAVE_USLEEP 1
|
||||
|
||||
/* Define if lex/flex has yylex_destroy */
|
||||
#define HAVE_YYLEX_DESTROY 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "avrdude"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "avrdude-dev@nongnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "avrdude"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "avrdude 6.3-20160220"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "avrdude"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "6.3-20160220"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "6.3-20160220"
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#define YYTEXT_POINTER 1
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
194
src/avrdude/ac_cfg.h.in
Normal file
194
src/avrdude/ac_cfg.h.in
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/* ac_cfg.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <ddk/hidsdi.h> header file. */
|
||||
#undef HAVE_DDK_HIDSDI_H
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the <hidapi/hidapi.h> header file. */
|
||||
#undef HAVE_HIDAPI_HIDAPI_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define if ELF support is enabled via libelf */
|
||||
#undef HAVE_LIBELF
|
||||
|
||||
/* Define to 1 if you have the <libelf.h> header file. */
|
||||
#undef HAVE_LIBELF_H
|
||||
|
||||
/* Define to 1 if you have the <libelf/libelf.h> header file. */
|
||||
#undef HAVE_LIBELF_LIBELF_H
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi */
|
||||
#undef HAVE_LIBFTDI
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi1 */
|
||||
#undef HAVE_LIBFTDI1
|
||||
|
||||
/* Define if libftdi supports FT232H, libftdi version >= 0.20 */
|
||||
#undef HAVE_LIBFTDI_TYPE_232H
|
||||
|
||||
/* Define if HID support is enabled via the Win32 DDK */
|
||||
#undef HAVE_LIBHID
|
||||
|
||||
/* Define if HID support is enabled via libhidapi */
|
||||
#undef HAVE_LIBHIDAPI
|
||||
|
||||
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||
#undef HAVE_LIBNCURSES
|
||||
|
||||
/* Define to 1 if you have the `readline' library (-lreadline). */
|
||||
#undef HAVE_LIBREADLINE
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
#undef HAVE_LIBTERMCAP
|
||||
|
||||
/* Define if USB support is enabled via libusb */
|
||||
#undef HAVE_LIBUSB
|
||||
|
||||
/* Define if USB support is enabled via a libusb-1.0 compatible libusb */
|
||||
#undef HAVE_LIBUSB_1_0
|
||||
|
||||
/* Define to 1 if you have the <libusb-1.0/libusb.h> header file. */
|
||||
#undef HAVE_LIBUSB_1_0_LIBUSB_H
|
||||
|
||||
/* Define to 1 if you have the <libusb.h> header file. */
|
||||
#undef HAVE_LIBUSB_H
|
||||
|
||||
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
|
||||
#undef HAVE_LIBWS2_32
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Linux sysfs GPIO support enabled */
|
||||
#undef HAVE_LINUXGPIO
|
||||
|
||||
/* Define to 1 if you have the <lusb0_usb.h> header file. */
|
||||
#undef HAVE_LUSB0_USB_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#undef HAVE_MEMSET
|
||||
|
||||
/* parallel port access enabled */
|
||||
#undef HAVE_PARPORT
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#undef HAVE_STRNCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#undef HAVE_STRTOL
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint_t'. */
|
||||
#undef HAVE_UINT_T
|
||||
|
||||
/* Define to 1 if the system has the type `ulong_t'. */
|
||||
#undef HAVE_ULONG_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the <usb.h> header file. */
|
||||
#undef HAVE_USB_H
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define if lex/flex has yylex_destroy */
|
||||
#undef HAVE_YYLEX_DESTROY
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
188
src/avrdude/arduino.c
Normal file
188
src/avrdude/arduino.c
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Arduino programmer
|
||||
*
|
||||
* The Arduino programmer is mostly a STK500v1, just the signature bytes
|
||||
* are read differently.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
#include "stk500_private.h"
|
||||
#include "stk500.h"
|
||||
#include "arduino.h"
|
||||
|
||||
/* read signature bytes - arduino version */
|
||||
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
if (m->size < 3) {
|
||||
avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = Cmnd_STK_READ_SIGN;
|
||||
buf[1] = Sync_CRC_EOP;
|
||||
|
||||
serial_send(&pgm->fd, buf, 2);
|
||||
|
||||
if (serial_recv(&pgm->fd, buf, 5) < 0)
|
||||
return -1;
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
avrdude_message(MSG_INFO, "%s: stk500_cmd(): programmer is out of sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
} else if (buf[0] != Resp_STK_INSYNC) {
|
||||
avrdude_message(MSG_INFO, "\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -2;
|
||||
}
|
||||
if (buf[4] != Resp_STK_OK) {
|
||||
avrdude_message(MSG_INFO, "\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_OK, buf[4]);
|
||||
return -3;
|
||||
}
|
||||
|
||||
m->buf[0] = buf[1];
|
||||
m->buf[1] = buf[2];
|
||||
m->buf[2] = buf[3];
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int prusa_init_external_flash(PROGRAMMER * pgm)
|
||||
{
|
||||
// Note: send/receive as in _the firmare_ send & receives
|
||||
const char entry_magic_send [] = "start\n";
|
||||
const char entry_magic_receive[] = "w25x20cl_enter\n";
|
||||
const char entry_magic_cfm [] = "w25x20cl_cfm\n";
|
||||
const size_t buffer_len = 32; // Should be large enough for the above messages
|
||||
|
||||
int res;
|
||||
size_t recv_size;
|
||||
char *buffer = alloca(buffer_len);
|
||||
|
||||
// 1. receive the "start" command
|
||||
recv_size = sizeof(entry_magic_send) - 1;
|
||||
res = serial_recv(&pgm->fd, buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
} else if (strncmp(buffer, entry_magic_send, recv_size) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer emitted incorrect start code: `%*s`\n", progname, recv_size, buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. Send the external flash programmer enter command
|
||||
if (serial_send(&pgm->fd, entry_magic_receive, sizeof(entry_magic_receive) - 1) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): Failed to send command to the printer\n",progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 3. Receive the entry confirmation command
|
||||
recv_size = sizeof(entry_magic_cfm) - 1;
|
||||
res = serial_recv(&pgm->fd, buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
} else if (strncmp(buffer, entry_magic_cfm, recv_size) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer emitted incorrect cfm code: `%*s`\n", progname, recv_size, buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arduino_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
union pinfo pinfo;
|
||||
strcpy(pgm->port, port);
|
||||
pinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
|
||||
if (serial_open(port, pinfo, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear DTR and RTS to unload the RESET capacitor
|
||||
* (for example in Arduino) */
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
usleep(250*1000);
|
||||
/* Set DTR and RTS back to high */
|
||||
serial_set_dtr_rts(&pgm->fd, 1);
|
||||
usleep(50*1000);
|
||||
|
||||
// Sometimes there may be line noise generating input on the printer's USB-to-serial IC
|
||||
// Here we try to clean its input buffer with a sequence of newlines (a minimum of 9 is needed):
|
||||
const char cleanup_newlines[] = "\n\n\n\n\n\n\n\n\n\n";
|
||||
if (serial_send(&pgm->fd, cleanup_newlines, sizeof(cleanup_newlines) - 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
// Initialization sequence for programming the external FLASH on the Prusa MK3
|
||||
if (prusa_init_external_flash(pgm) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: arduino_open(): Failed to initialize MK3 external flash programming mode\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arduino_close(PROGRAMMER * pgm)
|
||||
{
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
const char arduino_desc[] = "Arduino programmer";
|
||||
|
||||
void arduino_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
/* This is mostly a STK500; just the signature is read
|
||||
differently than on real STK500v1
|
||||
and the DTR signal is set when opening the serial port
|
||||
for the Auto-Reset feature */
|
||||
stk500_initpgm(pgm);
|
||||
|
||||
strcpy(pgm->type, "Arduino");
|
||||
pgm->read_sig_bytes = arduino_read_sig_bytes;
|
||||
pgm->open = arduino_open;
|
||||
pgm->close = arduino_close;
|
||||
}
|
||||
29
src/avrdude/arduino.h
Normal file
29
src/avrdude/arduino.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef arduino_h__
|
||||
#define arduino_h__
|
||||
|
||||
extern const char arduino_desc[];
|
||||
void arduino_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
BIN
src/avrdude/atmel-docs/AVR109.pdf
Normal file
BIN
src/avrdude/atmel-docs/AVR109.pdf
Normal file
Binary file not shown.
BIN
src/avrdude/atmel-docs/AVR910.pdf
Normal file
BIN
src/avrdude/atmel-docs/AVR910.pdf
Normal file
Binary file not shown.
BIN
src/avrdude/atmel-docs/AVRISPmkII-AVR069.pdf
Normal file
BIN
src/avrdude/atmel-docs/AVRISPmkII-AVR069.pdf
Normal file
Binary file not shown.
116
src/avrdude/atmel-docs/EDBG/common/browserDetect.js
Normal file
116
src/avrdude/atmel-docs/EDBG/common/browserDetect.js
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
var BrowserDetect = {
|
||||
init: function () {
|
||||
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
|
||||
this.version = this.searchVersion(navigator.userAgent)
|
||||
|| this.searchVersion(navigator.appVersion)
|
||||
|| "an unknown version";
|
||||
this.OS = this.searchString(this.dataOS) || "an unknown OS";
|
||||
},
|
||||
searchString: function (data) {
|
||||
for (var i=0;i<data.length;i++) {
|
||||
var dataString = data[i].string;
|
||||
var dataProp = data[i].prop;
|
||||
this.versionSearchString = data[i].versionSearch || data[i].identity;
|
||||
if (dataString) {
|
||||
if (dataString.indexOf(data[i].subString) != -1)
|
||||
return data[i].identity;
|
||||
}
|
||||
else if (dataProp)
|
||||
return data[i].identity;
|
||||
}
|
||||
},
|
||||
searchVersion: function (dataString) {
|
||||
var index = dataString.indexOf(this.versionSearchString);
|
||||
if (index == -1) return;
|
||||
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
|
||||
},
|
||||
dataBrowser: [
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "Chrome",
|
||||
identity: "Chrome"
|
||||
},
|
||||
{ string: navigator.userAgent,
|
||||
subString: "OmniWeb",
|
||||
versionSearch: "OmniWeb/",
|
||||
identity: "OmniWeb"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "Apple",
|
||||
identity: "Safari",
|
||||
versionSearch: "Version"
|
||||
},
|
||||
{
|
||||
prop: window.opera,
|
||||
identity: "Opera"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "iCab",
|
||||
identity: "iCab"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "KDE",
|
||||
identity: "Konqueror"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "Firefox",
|
||||
identity: "Firefox"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "Camino",
|
||||
identity: "Camino"
|
||||
},
|
||||
{ // for newer Netscapes (6+)
|
||||
string: navigator.userAgent,
|
||||
subString: "Netscape",
|
||||
identity: "Netscape"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "MSIE",
|
||||
identity: "Explorer",
|
||||
versionSearch: "MSIE"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "Gecko",
|
||||
identity: "Mozilla",
|
||||
versionSearch: "rv"
|
||||
},
|
||||
{ // for older Netscapes (4-)
|
||||
string: navigator.userAgent,
|
||||
subString: "Mozilla",
|
||||
identity: "Netscape",
|
||||
versionSearch: "Mozilla"
|
||||
}
|
||||
],
|
||||
dataOS : [
|
||||
{
|
||||
string: navigator.platform,
|
||||
subString: "Win",
|
||||
identity: "Windows"
|
||||
},
|
||||
{
|
||||
string: navigator.platform,
|
||||
subString: "Mac",
|
||||
identity: "Mac"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "iPhone",
|
||||
identity: "iPhone/iPod"
|
||||
},
|
||||
{
|
||||
string: navigator.platform,
|
||||
subString: "Linux",
|
||||
identity: "Linux"
|
||||
}
|
||||
]
|
||||
|
||||
};
|
||||
BrowserDetect.init();
|
||||
1
src/avrdude/atmel-docs/EDBG/common/css/960.css
Normal file
1
src/avrdude/atmel-docs/EDBG/common/css/960.css
Normal file
File diff suppressed because one or more lines are too long
227
src/avrdude/atmel-docs/EDBG/common/css/docbook.css
Normal file
227
src/avrdude/atmel-docs/EDBG/common/css/docbook.css
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
|
||||
/* RESETS */
|
||||
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, tt, var,b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { /* */
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
body { font: 12px Verdana, Geneva, sans-serif; }
|
||||
|
||||
@font-face {
|
||||
font-family: DroidSansMono;
|
||||
src: url("../fonts/DroidSansMono.eot") /* EOT file for IE */
|
||||
}
|
||||
@font-face {
|
||||
font-family: DroidSansMono;
|
||||
src: url("../fonts/DroidSansMono.ttf") /* TTF file for CSS3 browsers */
|
||||
}
|
||||
|
||||
p, ul, ol, li { font: 10pt Verdana, Geneva, sans-serif; }
|
||||
h1 { font: bold 15pt IntervalLight, sans-serif; }
|
||||
h2 { font: bold 14pt IntervalLight, sans-serif; }
|
||||
|
||||
h1, h2, h3 { color: #444;}
|
||||
h4, h5, h6 { color: #444;}
|
||||
h3, h4, h5, h6 {padding:10px 0px 2px 4px;}
|
||||
|
||||
.book h1, .chapter h2, .section h2 {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 18px;
|
||||
margin-bottom: 6px;
|
||||
border-bottom: 1px #CCC solid;
|
||||
}
|
||||
|
||||
|
||||
p {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
color: #444;
|
||||
/*width: 100%; Removing width so it's not fixed or floated */
|
||||
padding: 0px 10px 10px 5px; /* changed padding-right from 5 to 10 and padding-left from 10px to 5px */
|
||||
*padding: 5px 5px 10px 0px; /* IE7 hack */
|
||||
}
|
||||
|
||||
/* Page layout */
|
||||
div#content
|
||||
{
|
||||
padding: 1em 2em 1em 2em;
|
||||
}
|
||||
|
||||
.navfooter
|
||||
{
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.navfooter table td
|
||||
{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.mediaobject img
|
||||
{
|
||||
margin: 0.5em 0.5em 0.5em 0.5em;
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mediaobject img[align="left"]
|
||||
{
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.informalfigure { margin: 6px; }
|
||||
|
||||
/* "Layout" tables should not have borders */
|
||||
#content table, #content table td { border: none; }
|
||||
|
||||
/* Generic tables */
|
||||
#content .table table th, #content .informaltable table th { background-color: #585858 }
|
||||
#content .table table, #content .informaltable table
|
||||
{
|
||||
border-collapse:collapse;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#content .table tr:nth-child(odd), #content .informaltable tr:nth-child(odd)
|
||||
{
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
#content .table tr:nth-child(even), #content .informaltable tr:nth-child(even)
|
||||
{
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
|
||||
#content .table table td, #content .informaltable table td,
|
||||
#content .table table th, #content .informaltable table th
|
||||
{
|
||||
border: 1px solid #A7A9AB;
|
||||
}
|
||||
|
||||
#content .footnotes tr td
|
||||
{
|
||||
background-color:white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* Admonitions */
|
||||
div.note, div.caution, div.important, div.tip, div.warning
|
||||
{
|
||||
border: solid 1px #AAA;
|
||||
background: #ededed;
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
margin: 1em 0em 1em 0em;
|
||||
}
|
||||
|
||||
div.note *, div.caution *, div.important *, div.tip *, div.warning * {
|
||||
background: inherit !important;
|
||||
color: inherit !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* Program listing */
|
||||
.programlisting
|
||||
{
|
||||
/*width: auto;*/
|
||||
border: solid 1px #AAA;
|
||||
background: #ededed;
|
||||
padding: 1em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
overflow:hidden;
|
||||
font-family: DroidSansMono, Consolas
|
||||
}
|
||||
|
||||
|
||||
/* Lists */
|
||||
ul
|
||||
{
|
||||
list-style: square outside;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ul.square
|
||||
{
|
||||
list-style: square outside;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ul.circle, ul[type=disk]
|
||||
{
|
||||
list-style: disc outside;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ol
|
||||
{
|
||||
list-style-type: decimal;
|
||||
list-style: decimal;
|
||||
margin: 0 0 0 2.8em;
|
||||
padding: 0 0 1em 0;
|
||||
}
|
||||
li
|
||||
{
|
||||
padding-bottom: .3em;
|
||||
/*list-style: square;*/
|
||||
}
|
||||
li p
|
||||
{
|
||||
margin: 0 0 .25em 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ul ul.circle
|
||||
{
|
||||
margin-top: .3em;
|
||||
}
|
||||
ul ul.square
|
||||
{
|
||||
margin-top: .3em;
|
||||
}
|
||||
|
||||
ul, ol { margin-left: 3em; }
|
||||
/*
|
||||
dl dt { padding: 0px 10px 0px 5px;}
|
||||
*/
|
||||
div.orderedlist-collapsed
|
||||
{
|
||||
margin: 1em 0 0 1em;
|
||||
padding: 0 0 1em 0;
|
||||
font-size:smaller;
|
||||
}
|
||||
|
||||
div.orderedlist-collapsed span.listitem
|
||||
{
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.variablelist dt
|
||||
{
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
dl.toc
|
||||
{
|
||||
margin-left: 2em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.guibutton, .guimenu, .guimenuitem, .guisubmenu
|
||||
{
|
||||
font-family: Arial, Verdana, Geneva, sans-serif;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.disclaimer
|
||||
{
|
||||
font-size: 6pt;
|
||||
}
|
||||
154
src/avrdude/atmel-docs/EDBG/common/css/fluid_grid.css
Normal file
154
src/avrdude/atmel-docs/EDBG/common/css/fluid_grid.css
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
Variable Grid System (Fluid Version).
|
||||
Learn more ~ http://www.spry-soft.com/grids/
|
||||
Based on 960 Grid System - http://960.gs/ & 960 Fluid - http://www.designinfluences.com/
|
||||
|
||||
Licensed under GPL and MIT.
|
||||
*/
|
||||
|
||||
|
||||
/* Containers
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
.container_3 {
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
/* Grid >> Global
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.grid_1,
|
||||
.grid_2,
|
||||
.grid_3 {
|
||||
display:inline;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-left: 1%;
|
||||
margin-right: 1%;
|
||||
}
|
||||
|
||||
/* Grid >> Children (Alpha ~ First, Omega ~ Last)
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.alpha {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.omega {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* Grid >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .grid_1 {
|
||||
width:31.333%;
|
||||
}
|
||||
|
||||
.container_3 .grid_2 {
|
||||
width:64.667%;
|
||||
}
|
||||
|
||||
.container_3 .grid_3 {
|
||||
width:98.0%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Prefix Extra Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .prefix_1 {
|
||||
padding-left:33.333%;
|
||||
}
|
||||
|
||||
.container_3 .prefix_2 {
|
||||
padding-left:66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Suffix Extra Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .suffix_1 {
|
||||
padding-right:33.333%;
|
||||
}
|
||||
|
||||
.container_3 .suffix_2 {
|
||||
padding-right:66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Push Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .push_1 {
|
||||
left:33.333%;
|
||||
}
|
||||
|
||||
.container_3 .push_2 {
|
||||
left:66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Pull Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .pull_1 {
|
||||
left:-33.333%;
|
||||
}
|
||||
|
||||
.container_3 .pull_2 {
|
||||
left:-66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Clear Floated Elements
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* http://sonspring.com/journal/clearing-floats */
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* http://perishablepress.com/press/2008/02/05/lessons-learned-concerning-the-clearfix-css-hack */
|
||||
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
content: ' ';
|
||||
display: block;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
* html .clearfix {
|
||||
height: 1%;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
display: block;
|
||||
}
|
||||
59
src/avrdude/atmel-docs/EDBG/common/css/index.css
Normal file
59
src/avrdude/atmel-docs/EDBG/common/css/index.css
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
body {
|
||||
font-size: 12px;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
|
||||
.a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 31px 0 0 0;
|
||||
}
|
||||
|
||||
.group
|
||||
{
|
||||
/*background-color: pink;*/
|
||||
width:966px;
|
||||
}
|
||||
|
||||
.group_header {
|
||||
color: #0066CB;
|
||||
font: bold 14pt IntervalLight, sans-serif;
|
||||
text-decoration: none;
|
||||
padding: 8px;
|
||||
background-color: #EEEEEE;
|
||||
margin-top: 24px;
|
||||
/*margin-bottom: 8px;*/
|
||||
}
|
||||
|
||||
.products
|
||||
{
|
||||
float:left;
|
||||
/*background:#FFF8F8;*/
|
||||
}
|
||||
|
||||
.product {
|
||||
/*background: url("../images/panelbg.png") 0 0 no-repeat;*/
|
||||
width: 300px;
|
||||
height: 130px;
|
||||
/*margin-left: 20px;*/
|
||||
padding: 10px;
|
||||
border: 1px solid #EEEEEE;
|
||||
display:block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.product span {
|
||||
font-size: 16px;
|
||||
color: #0066CB;
|
||||
margin-bottom: 8px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.product img
|
||||
{
|
||||
margin-right:12px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
493
src/avrdude/atmel-docs/EDBG/common/css/positioning.css
Normal file
493
src/avrdude/atmel-docs/EDBG/common/css/positioning.css
Normal file
|
|
@ -0,0 +1,493 @@
|
|||
tr th .added { color: #E6E6FA; }
|
||||
tr th .changed {color: #99ff99; }
|
||||
div.added tr, div.added { background-color: #E6E6FA; }
|
||||
div.deleted tr, div.deleted { text-decoration: line-through;
|
||||
background-color: #FF7F7F; }
|
||||
div.changed tr, div.changed { background-color: #99ff99; }
|
||||
div.off { }
|
||||
|
||||
span.added { background-color: #E6E6FA; }
|
||||
span.deleted { text-decoration: line-through;
|
||||
background-color: #FF7F7F; }
|
||||
span.changed { background-color: #99ff99; }
|
||||
span.off { }
|
||||
|
||||
|
||||
body { font: 12px Verdana, Geneva, sans-serif; }
|
||||
p, ul, ol, li { font: 10pt Verdana, Geneva, sans-serif; }
|
||||
h1 { font: 15pt Arial, Helvetica, geneva;
|
||||
color: black!important;
|
||||
}
|
||||
h2 { font: normal 12pt Arial, Helvetica, geneva; }
|
||||
|
||||
#header {
|
||||
background: white;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 99px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: auto;
|
||||
left: 0;
|
||||
border-bottom: 1px solid #bbc4c5;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin-left: 310px;
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: -15px;
|
||||
color: #404040 !important;
|
||||
}
|
||||
|
||||
|
||||
#header h1 {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
|
||||
p.breadcrumbs {
|
||||
margin-top: 30px;
|
||||
margin-left: 310px;
|
||||
}
|
||||
|
||||
#header img {
|
||||
float: left;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#header p.breadcrumbs a {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
#leftnavigation {
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
height: auto;
|
||||
top:100px;
|
||||
/*right:10px;*/
|
||||
/*left:10px;*/
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width:inherit;
|
||||
z-index: 1500;
|
||||
border-right:2px solid #bbc4c5;
|
||||
padding:1px;
|
||||
background-color: #ededed!important;
|
||||
}
|
||||
|
||||
#treeDiv {
|
||||
overflow: auto;
|
||||
/* position: fixed;*/
|
||||
height: auto;
|
||||
top: 136px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
/* width: 18%;*/
|
||||
z-index: 1500;
|
||||
/* border-right:2px solid #CCCCCC;
|
||||
background-color: #f0f0f0!important;*/
|
||||
}
|
||||
|
||||
/*#searchDiv {
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
height: auto;
|
||||
top: 138px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 243px;
|
||||
z-index: 1500;
|
||||
border-right:2px solid #CCCCCC;
|
||||
background-color: #f0f0f0!important;
|
||||
}*/
|
||||
|
||||
#content {
|
||||
position: relative;
|
||||
top: 90px; /*left: 240px;*/
|
||||
right: auto; bottom: 20px;
|
||||
/*margin: 0px 0px 0px 280px;*/
|
||||
width: auto;
|
||||
height: inherit;
|
||||
padding-left: 5px;
|
||||
padding-right: 30px;
|
||||
border-left: 1px solid #cccccc;
|
||||
overflow :scroll;
|
||||
overflow-x:auto;
|
||||
z-index: 1000;
|
||||
|
||||
}
|
||||
|
||||
#navheader {
|
||||
position: fixed;
|
||||
background: #DCDCDC;
|
||||
padding-left: 10px;
|
||||
right: 0px;
|
||||
top: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#content h1, #content h2 {
|
||||
color: #404040 !important;
|
||||
font-size: 170%;
|
||||
font-weight: normal;
|
||||
}
|
||||
.navfooter { bottom: 2%; }
|
||||
.highlight { background-color: #c5d3c3; }
|
||||
.highlightButton{ font-size: 0; }
|
||||
|
||||
/* Show Hide TOC tree */
|
||||
.pointLeft {
|
||||
padding-right: 15px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pointRight {
|
||||
padding-right: 15px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Search results Styling */
|
||||
.searchExpression {
|
||||
color: #0050A0;
|
||||
background-color: #EBEFF8;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.searchresult li a {
|
||||
text-decoration: none;
|
||||
color: #0050A0;
|
||||
}
|
||||
.searchresult li { color: #0050A0; }
|
||||
.shortdesclink { color: gray; font-size: 9pt; }
|
||||
.searchText { float:left;width:150px; }
|
||||
.searchButton {
|
||||
padding: 2px 12px 2px 12px;
|
||||
background-color:#bbb;
|
||||
border:#bbb solid 1pt;
|
||||
font-weight: bold;
|
||||
font-size: 10pt
|
||||
}
|
||||
.searchButton:hover{
|
||||
background-color: #cccccc;
|
||||
}
|
||||
.searchFieldSet {}
|
||||
|
||||
.title, div.toc>p{ font-weight: bold; }
|
||||
|
||||
p.breadcrumbs {
|
||||
display: inline;
|
||||
margin-bottom: 0px;
|
||||
margin-top: 33px;
|
||||
}
|
||||
|
||||
p.breadcrumbs a {
|
||||
padding-right: 12px;
|
||||
margin-right: 5px;
|
||||
text-decoration: none;
|
||||
color: #575757;
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
p.breadcrumbs a:first-child {background: url(../images/breadcrumb-arrow-white.png) no-repeat right center;}
|
||||
|
||||
p.breadcrumbs a:hover {text-decoration: underline;}
|
||||
|
||||
#star ul.star {
|
||||
LIST-STYLE: none;
|
||||
MARGIN: 0;
|
||||
PADDING: 0;
|
||||
WIDTH: 85px;
|
||||
/* was 100 */
|
||||
HEIGHT: 20px;
|
||||
LEFT: 1px;
|
||||
TOP: -5px;
|
||||
POSITION: relative;
|
||||
FLOAT: right;
|
||||
BACKGROUND: url('../images/starsSmall.png') repeat-x 0 -25px;
|
||||
}
|
||||
#star li {
|
||||
PADDING: 0;
|
||||
MARGIN: 0;
|
||||
FLOAT: right;
|
||||
DISPLAY: block;
|
||||
WIDTH: 85px;
|
||||
/* was 100 */
|
||||
HEIGHT: 20px;
|
||||
TEXT-DECORATION: none;
|
||||
text-indent: -9000px;
|
||||
Z-INDEX: 20;
|
||||
POSITION: absolute;
|
||||
PADDING: 0;
|
||||
}
|
||||
#star li.curr {
|
||||
BACKGROUND: url('../images/starsSmall.png') left 25px;
|
||||
FONT-SIZE: 1px;
|
||||
}
|
||||
|
||||
table.navLinks {margin-right: 20px;}
|
||||
|
||||
table.navLinks td a {
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
color: black;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
a.navLinkPrevious {
|
||||
padding-left: 12px;
|
||||
background: url(../images/previous-arrow.png) no-repeat left center;
|
||||
}
|
||||
|
||||
a.navLinkNext {
|
||||
padding-right: 12px;
|
||||
background: url(../images/next-arrow.png) no-repeat right center;
|
||||
}
|
||||
|
||||
a#showHideButton {
|
||||
padding-left: 20px;
|
||||
background: url(../images/sidebar.png) no-repeat left center;
|
||||
}
|
||||
|
||||
|
||||
.filetree li span a { color: #777; }
|
||||
|
||||
#treediv { -webkit-box-shadow: #CCC 0px 1px 2px 0px inset; }
|
||||
|
||||
.legal, .legal *{
|
||||
color: #555;
|
||||
text-align: center;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.internal { color : #0000CC;}
|
||||
|
||||
.writeronly {color : red;}
|
||||
|
||||
.remark, .remark .added, .remark .changed, .remark .deleted{ background: yellow;}
|
||||
|
||||
tr th, tr th .internal, tr th .added, tr th .changed {
|
||||
background: #00589E;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.statustext{
|
||||
position:fixed;
|
||||
top:105px;
|
||||
width: 0%;
|
||||
height: 0%;
|
||||
opacity: .3;
|
||||
-webkit-transform: rotate(90deg);
|
||||
-moz-transform: rotate(90deg);
|
||||
-o-transform: rotate(90deg);
|
||||
white-space: nowrap;
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
#toolbar {
|
||||
width: 100%;
|
||||
height: 33px;
|
||||
position: fixed;
|
||||
top: 93px;
|
||||
z-index: 99;
|
||||
left: 280px;
|
||||
color: #333;
|
||||
line-height: 28px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#toolbar-left {
|
||||
position: relative;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
body p.breadcrumbs {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
/*body #content {
|
||||
position: static;
|
||||
margin-top: 126px;
|
||||
top: 0px;
|
||||
}*/
|
||||
|
||||
body.sidebar #toolbar{left: 0px;}
|
||||
|
||||
body.sidebar #toolbar-left{left: 0px;}
|
||||
|
||||
div#toolbar-left img {vertical-align: text-top;}
|
||||
|
||||
div.note *, div.caution *, div.important *, div.tip *, div.warning * {
|
||||
background: inherit !important;
|
||||
color: inherit !important;
|
||||
border: inherit /*!important*/;
|
||||
}
|
||||
|
||||
#content table thead, #content table th, #content table th p{
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#content table caption{font-weight: bold;}
|
||||
|
||||
#content table td, #content table {border: 1px solid black;}
|
||||
|
||||
#content table td, #content table th { padding: 5px;}
|
||||
|
||||
#content table {margin-bottom: 20px;}
|
||||
|
||||
*[align = 'center']{ text-align: center;}
|
||||
|
||||
#content .qandaset>table, #content .qandaset>table td, #content .calloutlist table, #content .calloutlist table td, #content .navfooter table, #content .navfooter table td {
|
||||
border: 0px solid;
|
||||
}
|
||||
|
||||
#sidebar
|
||||
{
|
||||
position: fixed;
|
||||
margin: 0px;
|
||||
left: 0px;
|
||||
right: auto;
|
||||
top: 99px;
|
||||
bottom: 0px;
|
||||
height: 543px;
|
||||
z-index: 0;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#content, #content * {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#sidebar, .navfooter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#expanders {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
#expanders dt {
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 2px solid #cccccc;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
background: url(../images/plus.png) 0px 7px no-repeat;
|
||||
/*background: pink;*/
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#expanders dt h2 {
|
||||
font: bold 14pt IntervalLight, sans-serif;
|
||||
text-decoration: none;
|
||||
color: #0066CB;
|
||||
/*background-position: -16px 0;*/
|
||||
padding-left: 13px;
|
||||
}
|
||||
|
||||
#expanders dt.plus {
|
||||
background: url(../images/plus.png) 0px 7px no-repeat;
|
||||
}
|
||||
|
||||
#expanders dt.minus {
|
||||
background: url(../images/minus.png) 0px 7px no-repeat;
|
||||
}
|
||||
|
||||
|
||||
#expanders dd {
|
||||
display: none;
|
||||
margin-bottom: 3em;
|
||||
/*background: yellow;*/
|
||||
}
|
||||
|
||||
#expanders .hitarea {
|
||||
background: url(../images/ui-icons_217bc0_256x240.png) 0 -208px no-repeat;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* fix for IE6 */
|
||||
/** html .hitarea {
|
||||
display: inline;
|
||||
float:none;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
#expanders .prod
|
||||
{
|
||||
width: 300px;
|
||||
border: #DDD solid 1px;
|
||||
float: left;
|
||||
margin: 1px;
|
||||
height: 160px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
#expanders .prodimg
|
||||
{
|
||||
/*border: #DDD solid 1px;*/
|
||||
float: left;
|
||||
}
|
||||
|
||||
.prodimg img {
|
||||
display: block;
|
||||
margin-left: 3px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
width: 100px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#expanders .prodtext
|
||||
{
|
||||
/*background: #F8F8F8;*/
|
||||
width: 165px;
|
||||
float: left;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
#expanders .prod p {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#expanders ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
#expanders li {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
a.external {
|
||||
background: url("../images/external_link.gif") no-repeat scroll right top transparent;
|
||||
padding: 0 13px 0 0;
|
||||
}
|
||||
28
src/avrdude/atmel-docs/EDBG/common/css/print.css
Normal file
28
src/avrdude/atmel-docs/EDBG/common/css/print.css
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
body {
|
||||
color : #000000 !important;
|
||||
background : #ffffff !important;
|
||||
font-family : "Times New Roman", Times, serif !important;
|
||||
font-size : 12pt !important;
|
||||
}
|
||||
|
||||
#sidebar, #sidebar-resizer, #header-resizer, #header { display: none !important;}
|
||||
|
||||
#content {
|
||||
position: absolute !important;
|
||||
margin: 0px !important;
|
||||
left: 0px !important;
|
||||
right: auto !important;
|
||||
top: 0px !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
overflow-x: visible !important;
|
||||
border-left: 0px solid #000000 !important;
|
||||
}
|
||||
|
||||
.ui-layout-container {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.mediaobject {
|
||||
text-align: left !important;
|
||||
}
|
||||
1
src/avrdude/atmel-docs/EDBG/common/css/reset.css
Normal file
1
src/avrdude/atmel-docs/EDBG/common/css/reset.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,dialog,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,html,i,iframe,img,ins,kbd,label,legend,li,main,mark,menu,meter,nav,object,ol,output,p,pre,progress,q,rp,rt,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video,xmp{border:0;margin:0;padding:0;font-size:100%}html,body{height:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section{display:block}b,strong{font-weight:bold}img{color:transparent;font-size:0;vertical-align:middle;-ms-interpolation-mode:bicubic}ol,ul{list-style:none}li{display:list-item}table{border-collapse:collapse;border-spacing:0}th,td,caption{font-weight:normal;vertical-align:top;text-align:left}q{quotes:none}q:before,q:after{content:'';content:none}sub,sup,small{font-size:75%}sub,sup{line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}svg{overflow:hidden}
|
||||
1
src/avrdude/atmel-docs/EDBG/common/css/text.css
Normal file
1
src/avrdude/atmel-docs/EDBG/common/css/text.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
body{font:13px/1.5 'Helvetica Neue',Arial,'Liberation Sans',FreeSans,sans-serif}pre,code{font-family:'DejaVu Sans Mono',Menlo,Consolas,monospace}hr{border:0 solid #ccc;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:disc}li{margin-left:30px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset,figure{margin-bottom:20px}
|
||||
BIN
src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.eot
Normal file
BIN
src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.eot
Normal file
Binary file not shown.
BIN
src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.ttf
Normal file
BIN
src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.ttf
Normal file
Binary file not shown.
BIN
src/avrdude/atmel-docs/EDBG/common/images/Book_Closed.png
Normal file
BIN
src/avrdude/atmel-docs/EDBG/common/images/Book_Closed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/avrdude/atmel-docs/EDBG/common/images/Book_Open.png
Normal file
BIN
src/avrdude/atmel-docs/EDBG/common/images/Book_Open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 703 B |
BIN
src/avrdude/atmel-docs/EDBG/common/images/Document_Text.png
Normal file
BIN
src/avrdude/atmel-docs/EDBG/common/images/Document_Text.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 583 B |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue